事务四大特性(ACID)
(1)原子性(Atomic)
指事务是一个不可分割的工作单位(像原子一样),事务中的操作要么都发生,要么都不发生。实现事务的原子性,要支持回滚操作,在某个操作失败后,回滚到事务执行之前的状态。
A和B都有1000块钱,A向B转账300,分为两个步骤,首先A=1000-300,然后B=1000+300。这两个步骤无论哪一个出错,都会失败,然后回滚到最初始状态。所以这两个步骤只能一起成功,或者一起失败,不能只发生其中一个动作。
(2)一致性(Consistency)
事务前后数据的完整性必须保持一致,事务完成后要符合逻辑运算。
A和B都有1000块钱,A向B转账300,转账前AB的钱都是1000块,他们共有2000块。转账后A的钱为700块,B的钱为1300块,他们依然共有2000块。转账前后符合逻辑运算,钱的总和事务前后未发生变化,符合一致性原则。
(3)隔离性(Isolation)
在并发数据操作时,不同的事务拥有各自的数据空间,它们的操作不会对彼此产生干 扰。用于解决并发事务的相互影响(脏读、不可重复读、幻读,第一类丢失更新,第二类丢失更新)
脏读:
事务A读到了事务B未提交的数据,然后进行了其他一些操作,事务B如果因为某些原因回滚了,那么事务A读取的数据就是脏数据。
时间段 | 事务A(取款) | 事务B(存款) |
---|---|---|
T1 | 开始事务 | |
T2 | 开始事务 | 查询余额为1000元 |
T3 | 存入200元 | |
T4 | 查询余额为1200元 | 余额为1200元 |
T5 | 取出400元 | 因某些原因进行回滚 |
T6 | 余额为800元 | 余额为1000元 |
T7 | 提交事务 | 提交事务 |
不可重复读:
事务A两次读取数据得到的结果不一样,在此过程中其他事务对数据进行了更新操作(update),并提交了事务。
时间段 | 事务A(查询余额) | 事务B(存款) |
---|---|---|
T1 | 开始事务 | 开始事务 |
T2 | 第一次查询余额为1000元 | 查询余额为1000元 |
T3 | 存入200元 | |
T4 | 余额为1200元 | |
T5 | 提交事务 | |
T6 | 第二次查询余额为1200元 | |
T7 | 提交事务 |
幻读:
事务A两次读取数据得到的结果不一样,在此过程中其它事务对数据进行新增(insert)或删除(delete)操作,并提交了事务。
时间段 | 事务A(注册账号) | 事务B(注册账号) |
---|---|---|
T1 | 开始事务 | 开始事务 |
T2 | 得到所要注册的账号为001 | 得到所要注册的账号为001 |
T3 | 查数据库不存在001的账号 | 查数据库不存在001的账号 |
T4 | insert操作(注册成功) | |
T5 | 提交事务 | |
T6 | insert操作(注册失败,001账号已存在) | |
T7 | 提交事务 |
第一类丢失更新:
回滚丢失,A事务回滚操作时,覆盖B事务已经提交的事务(关系型数据库以避免其发生)
时间段 | 事务A(取款) | 事务B(存款) |
---|---|---|
T1 | 开始事务 | 开始事务 |
T2 | 查询余额为1000元 | 查询余额为1000元 |
T3 | 取出400元 | 存入200元 |
T4 | 余额为600元 | 余额为1200元 |
T5 | 提交事务 | |
T6 | 回滚事务 | |
T7 | 余额为1000元(丢失更新,账户损失200元) |
第二类丢失更新:
提交丢失,A事务提交事务时,覆盖B事务已提交的事务(同不可重复读)
时间段 | 事务A(取款) | 事务B(取款) |
---|---|---|
T1 | 开始事务 | 开始事务 |
T2 | 查询余额为1000元 | 查询余额为1000元 |
T3 | 取出400元 | 取出200元 |
T4 | 余额为600元 | 余额为800元 |
T5 | 提交事务 | |
T6 | 提交事务 | |
T7 | 余额为600元(丢失更新,银行损失200元) |
总结:
脏读:A事务读到未提交的B事务,然后B事务回滚了;
不可重复读:A事务读到已提交的B事务(更新),B事务提交前后导致A事务两次读取的结果不同
幻读:A事务读到已提交的B事务(增删),B事务提交前后导致A事务两次读取的结果不同
第一类丢失更新:回滚丢失,A事务回滚,导致B事务丢失数据
第二类丢失更新:提交覆盖丢失,B事务先提交,A事务后提交,覆盖了B事务
数据库隔离级别
设置 | 描述 |
---|---|
Serializable | 可避免脏读、不可重复读、幻读情况的发生 |
Repeatable read | 可避免脏读、不可重复读情况的发生 |
Read committed | 可避免脏读情况发生 |
Read uncommitted | 最低级别,以上情况均无法保证 |
(3) 持久性(Durability)
事务提交后,对系统的影响是永久的。事务结束后的数据不随着外界原因导致数据丢失。
A和B都有1000块钱,A向B转账300,转账前如果断电或系统故障,重启数据库后A和B的钱都应该为1000块。如果转账后断电或系统故障,重启数据库后A的钱应该为700,B的钱应该为1300。