文章目录提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言一、Spring的事务
1.Spring事务传播行为2.隔离级别二、Spring事务失效的几种原因三、事务怎么做参考文章
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、Spring的事务Spring 事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring 是 无法提供事务功能的。真正的数据库层的事务提交和回滚是通过 binlog 或者 redo log 实 现的。
spring 事务实现主要有两种方法
1、编程式,beginTransaction()、commit()、rollback()等事务管理相关的方法
2、声明式,利用注解 Transactional 或者 aop 配置
事务传播是spirng对事务的一个强大支持,采用了动态代理的方法,对事务的一种加强操作,让开启了事务的方法和方法之间的调用更加灵活,例如:A,B两个方法都开启了事务,若A方法调用了B方法,若采用的是spring的事务管理,就产生了事务方法的相互调用问题,默认情况下,B方法的事务会被A方法覆盖,若此时B方法的事务要独立于A方法外的话,就可以采用事务传播来解决。
① PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前 存在事务,就加入该事务,该设置是最常用的设置。
② PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务, 如果当前不存在事务,就以非事务执行。
③ PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事 务,如果当前不存在事务,就抛出异常。
④ PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建 新事务。
⑤ PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务, 就把当前事务挂起
⑥ PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
⑦ PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前 没有事务,则按 REQUIRED 属性执行。
2.隔离级别设置隔离界别:用@Transactional 注解声明式事务的事务管理中来设置 isolation 属性的隔离级别 在配置文件中设置事务tx:method元素
ISOLATION 隔离的意思
① ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的隔离级别, 使用数据库默认的事务隔离级别。
② ISOLATION_READ_UNCOMMITTED:读未提交,允许另外一个事务可以看到这个 事务未提交的数据。
③ ISOLATION_READ_COMMITTED:读已提交,保证一个事务修改的数据提交后才 能被另一事务读取,而且能看到该事务对已有记录的更新。解决脏读问题
④ ISOLATION_REPEATABLE_READ:可重复读,保证一个事务修改的数据提交后才 能被另一事务读取,但是不能看到该事务对已有记录的更新。行锁
⑤ ISOLATION_SERIALIZABLE:一个事务在执行的过程中完全看不到其他事务对数据 库所做的更新。表锁
脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插 入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。
不可重复读 :是指在一个事务内,多次读同一数据
幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查 询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。 发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据, 同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了
二、Spring事务失效的几种原因spring的事务注解 @Transactional只能放在public修饰的方法上才起作用 ,如果放在其他非public(private,protected)方法上,虽然不报错,但是事务不起作用
如果采用spring+spring mvc,则context:component-scan重复扫描问题可能会引起事务失败。
如使用mysql且引擎是MyISAM,则事务会不起作用,原因是MyISAM不支持事务,可以改成InnoDB引擎
@Transactional 注解开启配置,必须放到listener里加载,如果放到DispatcherServlet的配置里,事务也是不起作用的。
Spring团队建议在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。在接口上使用 @Transactional 注解,只能当你设置了基于接口的代理时它才生效。因为注解是 不能继承 的,这就意味着如果正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装。
在业务代码中如果抛出RuntimeException异常,事务回滚;但是抛出Exception,事务不回滚;
如果在加有事务的方法内,使用了try…catch…语句块对异常进行了捕获,而catch语句块没有throw new RuntimeExecption异常,事务也不会回滚
在类A里面有方法a 和方法b, 然后方法b上面用 @Transactional加了方法级别的事务,在方法a里面 调用了方法b, 方法b里面的事务不会生效。原因是在同一个类之中,方法互相调用,切面无效 ,而不仅仅是事务。这里事务之所以无效,是因为spring的事务是通过aop实现的。
(1)原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback) 到事务开始前的状态,就像这个事务从来没有执行过一样。
(2)一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
(3)隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能, 事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆, 必须串行化或序列化 请 求,使得在同一时间仅有一个请求用于同一数据。
(4)持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
参考文章作者:一路奔跑1314:Spring事务失效的几种原因



