首页 > 其他 > 详细

今天必须搞懂事务

时间:2019-12-03 18:30:18      阅读:78      评论:0      收藏:0      [点我收藏+]

四个特性

原子性:操作一组指令,要么全部成功,要么全部失败。

一致性:比如转账,无论你做什么操作,最后的总钱数不会改变。

隔离性:两个事务并发进行,并发事务之间要相互隔离。

持久性:事务完成后,对数据的改变是永久的。

并发事务导致的问题

脏读:一个事务读取了另一个事务未提交的数据,之后未提交的事务回滚了。

幻读:一个事务执行两次,发现查询到的数据多了,或者少了。

不可重复度:事务A读取了一个数据 num = 1,事务A还没有提交,但是事务B修改 num = 2 提交了, 事务A再次读物num的时候,发现数据变了。

脏读和不可重复读的区别:脏读是A事务读取了B事务没有提交的数据,然后B事务回滚了

? 不可重复读是A事务读取了B事务没有提交和提交后的数据。

事务的隔离级别

读未提交:顾名思义,就是一个事务可以读取到另一个事务没有提交的事务,可能出现脏读。

? 解决:Read committed (读提交)

读提交:就是一个事务需要等到另一个事务提交之后才能读取数据,可能会出现不可重复读。

? 解决:Repeatable read(重复读)

重复度:开始读取数据的时候(事务开启),不再允许修改操作。但是可能会出现幻读。

? 解决:serializable (序列化)

序列化:最高级别的事务隔离级别,事务串行化顺序执行。(一般不使用)

事务的七大传播行为

PROPAGATION_REQUIRED: A事务方法调用B事务方法,如果A事务方法的事务存在,那么B事务就 在A事务中运行,如果A事务不存在,那么就新建一个事务运行。

? 回滚:

? A事务如果存在,B事务就和A事务共用一个事务,那么无论哪儿发生异常,AB都会回滚

? A方法事务如果不存在,B事务会新建一个事务,那么只有B方法发生异常,才会导致B事 务回滚,A方法不受影响。

PROPAGATION_REQUIRES_NEW:A事务方法调用B事务方法,不管A事务是否存在,都会新建一个 事务来运行B事务。

? 回滚:如果B事务发生异常,A事务也会跟着回滚

? 如果A事务发生异常,B事务不会跟着回滚

上面两个是最常用的两种事务。

PROPAGATION_SUPPORTS: 支持当前事务,假设当前没有事务,就以非事务方式运行

PROPAGATION_MANDATORY:支持当前事务,假设当前没有事务,就抛出异常

PROPAGATION_NOT_SUPPORTED:以非事务方式运行操作。假设当前存在事务,就把当前事务挂起

PROPAGATION_NEVER:以非事务方式运行,假设当前存在事务,则抛出异常

PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION_REQUIRED类似的操作。

事务方法的嵌套调用问题:

在一个service内部,事务方法之间的嵌套调用,普通方法和事务方法之间的嵌套调用,都不会开启新的事务,因为spring的事务是通过动态代理实现的,但是动态代理最后都是要用原始对象调用方法的,原始对象调用就不会再次触发代理了。

? 解决方法:用代理对象去调用,spring的ioc用的就是动态代理,用@AutoWride注入的对象去调用这个方法就可以了。

MYSQL行锁表锁

用一个没有索引的字段做条件-----------表锁
技术分享图片

这个事务还没提交,我又发起一个事务
技术分享图片

这个事务就会等待上一个事务释放锁,但是我这儿更新的不是同一行。所以应该是表锁。

技术分享图片

用主键做条件

技术分享图片

再发起一个更新请求:

技术分享图片

提交成功了!!

再试试修改同一行的数据:

技术分享图片

再发起一个修改请求:

技术分享图片

嘿嘿嘿:果然在等待锁。技术分享图片

如果用其他的索引做条件呢??

技术分享图片

修改同一行数据会出现等待锁的现象。

技术分享图片

但修改不同行的数据不会

技术分享图片

所以innodb的表锁行锁问题:如果普通的crud是表锁,但是如果索引生效的crud就是行锁

今天必须搞懂事务

原文:https://www.cnblogs.com/jjpp/p/11977827.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!