数据库之事务

来源:互联网 发布:vb label标签 编辑:程序博客网 时间:2024/05/22 09:04

定义

事务是一组原子性的SQL查询,或者说一个独立的工作单元。如果数据库引擎能够成功地对数据库应用该组查询的全部语句,那么就执行该组查询。如果其中一条语句因为崩溃或其他原因无法执行,那么多有的语句都不会执行。也就是说,事务内的语句,要么全部执行成功,要么全部执行失败。通俗的讲,事务就是一件事情。是一个不可分割的整体,就像化学原子一样,是构成物质的最小单元。

ACID

原子性(Atomicity):一个事务被视为一个不可分割的最小工作单元,整个事务内的所有操作,要么全部执行,要么全部失败回滚,不可能只执行其中的一部分。一致性(Consistency):即执行完数据库操作后,数据不会被破坏。比如A账户转账给B账户,不能因为A账户扣了钱,而B账户没有扣钱。隔离性(Isolation):通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的。这里需要注意隔离级别,之后会详细讲。持久性(Durability):一旦事务提交,则其所做的修改就会永久保存到数据库中。

隔离级别

READ_UNCOMMITTED(未提交读)READ_COMMITTED(提交读)REPEATABLE_READ(可重复读)SERIALIZABLE(可串行化)从上往下,级别越来越高,并发性能越来越差,安全性越来越高。之所以定义这几种级别,主要是为了解决数据在高并发行下产生的问题:脏读(Dirty Read)不可重复读(Unrepeatable Read)幻读(Phantom Read)

脏读

                          并发执行的两个事务

这里写图片描述

余额应该为1500元才对。在T5时间点,事务A此时查询余额为0元,这个数据就是脏数据,它是事务B造成的,明显事务没有隔离,乱套了。所以脏读这件事情造成的后果非常严重,一定要解决。必须让事务隔离起来。

不可重复读

                              不可重复读示例

这里写图片描述

事务A其实除了查询了两次以外,其他什么事情都没有做,结果钱及从1000变成0了,这就是重复读。其实这样也是合理的,毕竟实务B提交了事务,将数据库结果进行了持久化,所以事务A再次读取时就自然发生了变化。这种现象基本是可以理解的,但有些特殊场景下却是不允许的。毕竟这种现象也是事务之间没有隔离所造成的。

幻读

                               幻读示例

这里写图片描述

事务A在T3时刻和T6时刻统计的总存款数不同,这就是幻读。虽然看起来正常,但在一些要求严格的系统中,比如银行,这是不允许的。

总结

脏读:事务A读取了事务B未提交的数据,并在这个基础上又做了其它操作。不可重复读:事务A读取了事务B已提交的更改数据。幻读:事务A读取了事务B已提交的新增数据。                        事务隔离级别

这里写图片描述