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都要管
相当于要锁表