mysql五种事务级别和脏读、不可重复读、幻读

Springboot 事务级别

  • 1.default,就是数据库设置成什么就是什么,mysql我本机的设置成4

  • 2.read_uncommitted,会出现脏读

  • 3.read_committed, 防止脏读用这个肯定不会脏读,写之后都是读新,写失败肯定读旧

  • 4.repeatable_read 防止不可重复读,不仅本事务,还要考虑其他事务对这行记录的影响

  • 5.serialization_read 防止幻读

mysql设置实例

set global/session transaction isolation level REPEATABLE READ;

//以上两个都设置,如果有不同,session的是具体优先,覆盖全局设置

要记住mysql有一个autocommit参数,默认是on,他的作用是每一条单独的查询都是一个事务,并且自动开始,自动提交(执行完以后就自动结束了,如果你要适用select for update,而不手动调用 start transaction,这个for update的行锁机制等于没用,因为行锁在自动提交后就释放了)

锁机制区分
  • 共享锁 由读表操作加上的锁(用于解决不看重复锁);读锁

  • 排他锁 写锁

锁范围区分
  • 行锁

  • 表锁


概念

脏读

read_uncommited 就是读到的数据和数据库时点实际数据不符合

根据cap的理论,这个是一致性问题,就是写之后,读到的都是写后数据;写失败,之后所有读请求不能读到这个新数据,本质上是操作顺序问题

脏读例子,就是一致性例子:张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。

与此同时,

事务B正在读取张三的工资,读取到张三的工资为8000。

随后,

事务A发生异常,而回滚了事务。张三的工资又回滚为5000。

最后,

事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读。

不可重复读

在事务A中,读取到张三的工资为5000,操作没有完成,事务还没提交。

与此同时,

事务B把张三的工资改为8000,并提交了事务。

随后,

在事务A中,再次读取张三的工资,此时工资变为8000。在一个事务中前后两次读取的结果并不致,导致了不可重复读。

关键是事务A中有多次读取,按照一致性原则,事务A的第一次读的结果在事务B提交后也要相应改变,或者B就不能提交

在可重复读中,该sql第一次读取到数据后,就将这些数据加锁(**读锁、行锁**),其它事务无法修改这些数据,就可以实现可重复 读了

幻读

同一事务中,用同样的操作读取两次,得到的记录数不相同(可能只在部分报表统计中有用,联机事务处理一般只针对单条的),幻读的侧重点在于两次读取的纪录数量不一致

insert都要管

相当于要锁表


【眼见为实】自己动手实践理解数据库READ UNCOMMITED && SERIALIZABLE

mysql关于幻读和不可重复读的解决方案

猜你喜欢

转载自blog.csdn.net/wxid2798226/article/details/81709537
今日推荐