mysql事务

事务的ACID特性

A:atomicity :原子性

C:consistency :一致性

I:isolation : 隔离性

D:durability :持久性

原子性:一个事务内的操作时不可分割的,即要么全部执行成功,要么全部执行失败回滚到初始状态

一致性:应用系统从一个正确的状态,到另外一个正确的状态(AID三个特性是保证C特性,假设列a有约束不小于0,那么在事务中将列a的值修改为-1,那么执行的时候将会报错,事务回滚)

隔离性:一个事务内的操作能否被另外一个事务看见的程度,不同的隔离级别下,情况不一样

持久性:事务一旦提交,那么事务内所做的操作就会被永久性保留下来。

MyISAM引擎

不支持事务

InnoDB引擎

支持事务,共有四种隔离级别:读未提交,读已提交,可重复读,串行化

默认隔离级别是可重复读且事务自动提交,可通过set autocommit = 0,修改当前会话事务不自动提交

不同级别下的事务又会引发这几种问题:脏读,幻读,不可重复读

不同级别事务会引起的问题如下表:(Y-会引起,N-不会引起)

InnoDB 中事务的实现是通过锁来实现的,采用“一致性非锁定读”的机制提高了并发性。

一致性非锁定读通过多版本并发控制(MVCC)实现,表示当前行如果被加了排它锁,其他事务在读取该记录时,其实读取的是历史快照数据。

脏读 不可重复读 幻读
读未提交(READ-UNCOMMITTED Y Y Y
读已提交(READ-COMMITTED N Y Y
可重复读(REPEATABLE-READ N N Y
串行化(SERIALIZABLE N N N

脏读

​ 当前事务读取到其他事务未提交的数据。

幻读

​ 当前事务在未提交之前,多次执行同样的查询sql,查询出的结果条数不一样,侧重在于结果集有新增或删除

不可重复读

​ 当前事务在未提交之前,多次执行同样的查询sql,查询的结果不一样,侧重在于结果数据更新

假设有以下表ttt,,结构如下:

id str
1 111
2 222
3 333

读未提交

​ 在该隔离级别下,当前事务可以读取到其他事务为提交的数据,会引发脏读,幻读,不可重复读三种问题。例如:脏读问题

  1. 分别在两个窗口a,b开启事务
  2. 窗口a执行 select * from ttt where id = 1; 结果集为id=1,str=111
  3. 窗口b执行 update ttt set str = 'aaa';
  4. 窗口a执行 select * from ttt where id = 1; 结果集为id=1,str=aaa

读已提交

​ 在该隔离级别下,当前事务可以读取到其他事务已提交的数据,会引发不可重复读,幻读问题。

例如:不可重复读问题

  1. 分别在两个窗口a,b开启事务
  2. 窗口a执行 select * from ttt where id = 1; 结果集为id=1,str=111
  3. 窗口b执行 update ttt set str = 'aaa';
  4. 窗口a执行 select * from ttt where id = 1; 结果集为id=1,str=111
  5. 窗口b执行 commit;
  6. 窗口a执行 select * from ttt where id = 1; 结果集为id=1,str=aaa

可重复读

​ 在该隔离级别下,当前事务前后读取的数据结果条数可能不一致,即幻读。例如:

  1. 分别在两个窗口a,b开启事务
  2. 窗口a执行 select * from ttt ; 结果集为id=1,2,3,str=111,222,333
  3. 窗口b执行 delete from ttt where id=1;
  4. 窗口a执行 select * from ttt ; 结果集为id=1,2,3,str=111,222,333
  5. 窗口b执行 commit;
  6. 窗口a执行 select * from ttt ; 结果集为id=2,3,str=222,333

串行化

​ 在该隔离级别下,当前事务读取到的数据前后一致,但并发性能最低。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容