事务的ACID

原子性(Atomic):事务中各项操作,要么全做要么全不做; 

一致性(Consistent):事务结束后系统状态是一致的;

隔离性(Isolated):并发执行的事务彼此无法看到对方的中间状态;

持久性(Durable):事务完成后所做的改动都会被持久化;

首先需要知道的是,只有存在并发数据访问时才需要事务。当多个事务访问同一数据时,可能会存在5类问题,包括3类数据读取问题(脏读、不可重复读和幻读)和2类数据更新问题(第1类丢失更新和第2类丢失更新)。

脏读(Dirty Read):A事务读取B事务尚未提交的数据。

时间转账事务A取款事务B
T1   开始事务
T2 开始事务  
T3   查询账户余额为1000元
T4   取出500元余额修改为500元
T5 查询账户余额为500元(脏读)  
T6   撤销事务余额恢复为1000元
T7 汇入100元把余额修改为600元  
T8 提交事务  

不可重复读(Unrepeatable Read):事务A重新读取前面读取过的数据,发现该数据已经被另一个已提交的事务B修改过了。两次读同一条数据的结果不一样

时间转账事务A取款事务B
T1   开始事务
T2 开始事务  
T3   查询账户余额为1000元
T4 查询账户余额为1000元  
T5   取出100元修改余额为900元
T6   提交事务
T7 查询账户余额为900元(不可重复读)  

幻读(Phantom Read):事务A重新执行一个查询,返回的结果和上一次查询的结果不一样,发现其中插入了被事务B提交的行。(修改了其他行数据,不可重复读是同一条数据)

时间统计金额事务A转账事务B
T1   开始事务
T2 开始事务  
T3 统计总存款为10000元  
T4   新增一个存款账户存入100元
T5   提交事务
T6 再次统计总存款为10100元(幻读)  

第1类丢失更新:事务A撤销时,覆盖了事务B已经更新的数据

时间取款事务A转账事务B
T1 开始事务  
T2   开始事务
T3 查询账户余额为1000元  
T4   查询账户余额为1000元
T5   汇入100元修改余额为1100元
T6   提交事务
T7 取出100元将余额修改为900元  
T8 撤销事务  
T9 余额恢复为1000元(丢失更新)  

第2类丢失更新:事务A覆盖事务B已经提交的数据,造成事务B所做的操作丢失。

时间转账事务A取款事务B
T1   开始事务
T2 开始事务  
T3   查询账户余额为1000元
T4 查询账户余额为1000元  
T5   取出100元将余额修改为900元
T6   提交事务
T7 汇入100元将余额修改为1100元  
T8 提交事务  
T9 查询账户余额为1100元(丢失更新)  

事务隔离级别

MySQL的事务隔离是在MySQL.ini配置文件里添加的,在文件的最后添加:transaction-isolation=REPEATABLE-READ
READ-UNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取
READ-COMMITTED:提交读,一个事务提交后才能被其他事务读取到
REPEATABLE-READ:可重复读,默认级别,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据
SERIALIZABLE:序列化,代价最高最可靠的隔离级别

事务隔离级别和数据访问的并发性是对立的,事务隔离级别越高并发性就越差。所以要根据具体的应用来确定合适的事务隔离级别,这个地方没有万能的原则。

隔离级别脏读不可重复读幻读第一类丢失更新第二类丢失更新
READ UNCOMMITED 允许 允许 允许 不允许 允许
READ COMMITTED 不允许 允许 允许 不允许 允许
REPEATABLE READ 不允许 不允许 允许 不允许 不允许
SERIALIZABLE 不允许 不允许 不允许 不允许 不允许

 

posted on 2019-08-01 15:59  zhangjinru123  阅读(187)  评论(0编辑  收藏  举报