事业单位网站模板,html5编辑器手机版下载,wordpress加载视频教程,中企动力做网站 知乎Spring事务的七种传播行为 1.事务的传播行为是什么#xff1f;2.具体传播行为2.1 REQUIRED #xff0c;默认#xff0c;存在事务则加入该事务#xff0c;不存在则新建一个事务2.2 REQUIRES_NEW#xff0c;每次新开启事务#xff0c;新老事务相互独立2.3 NESTED#xff0… Spring事务的七种传播行为 1.事务的传播行为是什么2.具体传播行为2.1 REQUIRED 默认存在事务则加入该事务不存在则新建一个事务2.2 REQUIRES_NEW每次新开启事务新老事务相互独立2.3 NESTED 存在事务则嵌套当中执行不存在事务则新建一个事务2.4 SUPPORTS存在则支持当前事务不存在事务则以非事务执行。2.5 NOT_SUPPORTED 以非事务的方式运行存在事务则把当前事务挂起2.6 MANDATORY强制事务执行不存在事务则抛出异常。2.7 NEVER以非事务来运行存在事务则抛出异常。 3.事务失效的场景3.1 非public修饰的方法3.2 自身调用3.3 被 final、static 关键字修饰的类或方法3.4 没有被 Spring 管理3.5 数据库不支持事务3.6 异常被捕获3.7 异常类型错误3.8 多线程调用 1.事务的传播行为是什么
事务的传播行为就是指多个声明了事务的方法相互调用的时候存在事务嵌套的问题事务在方法中如何传播。 比如说methodA()调用methodB(),两个方法都开启了事务那么methodB()是开启了一个新事物还是继续在methodA()这个事务中执行呢就取决与事务的传播行为。 所以Spring 为了解决这个问题定义了 7 种事务传播行为。
传播行为含义REQUIRED默认的Sring事务传播级别如果当前事务存在则加入该事务如果不存在 就新建一个事务。REQUIRES_NEW不管是否存在事务都会新开启一个事务新老事务相互独立外部事务抛出异常回滚不会影响内部事务的正常提交。NESTED如果当前存在事务则嵌套在当前事务中执行如果当前没有事务则新建一个事务类似与REQUIRE_NEW。SUPPORTS表示支持当前事务如果当前不存在事务则以非事务的方式执行。NOT_SUPPORTED表示以非事务的方式运行如果当前存在事务则把当前事务挂起。MANDATORY表示强制事务执行若当前不存在事务则抛出异常。NEVER表示以非事务的方式来运行如果当前存在事务则抛出异常。
2.具体传播行为
2.1 REQUIRED 默认存在事务则加入该事务不存在则新建一个事务
当前存在事务则加入该事务不存在事务则新建一个事务示例代码 OverrideTransactional(propagation Propagation.REQUIRED)public void methodA() {userMapper.updateById(new TbUser(2, 李开, 33, 1)); // 更新用户methodB(); //调用methodB()}OverrideTransactional(propagation Propagation.REQUIRED)public void methodB() {userMapper.updateById(new TbUser(3, 李福, 22, 1)); //更新用户int a 1/0; // 发生异常System.out.println(执行 methodB 完成);}结论用户数据不会发生变化。当调用methodA()上下文没有事务就会开启一个事务当执行methodB()因为已经存在一个事务methodB()不会开启新事务而是加入到methodA()事务中执行。当‘int a 1/0;’执行报错就会回滚methodA事务而methodB也在methodA事务中所有都会回滚。
2.2 REQUIRES_NEW每次新开启事务新老事务相互独立
不管是否存在事务都会新开启一个事务新老事务相互独立外部事务抛出异常回滚不会影响内部事务的正常提交。
2.3 NESTED 存在事务则嵌套当中执行不存在事务则新建一个事务
如果一个活动的事务存在则运行在一个嵌套事务中如果没有活动事务则按照PROPAGATION_REQUIRED属性执行。
2.4 SUPPORTS存在则支持当前事务不存在事务则以非事务执行。
如果存在事务则支持当前事务如果不存在事务则无事务运行
2.5 NOT_SUPPORTED 以非事务的方式运行存在事务则把当前事务挂起
表示以非事务的方式运行如果当前存在事务则把当前事务挂起。
2.6 MANDATORY强制事务执行不存在事务则抛出异常。
如果存在一个事务则事务的运行没有事务则抛出异常。
2.7 NEVER以非事务来运行存在事务则抛出异常。
总是非事务的运行如果存在一个活动的事务则抛出异常。
3.事务失效的场景
在方法上添加Transactional 注解后Spring 会基于这个类生成一个代理对象会将这个代理对象作为 bean当使用这个代理对象的方法时那么代理逻辑会先把事务的自动提交设置为 false然后再去执行具体的业务逻辑如果执行逻辑没有出现异常那么代理逻辑就会将事务进行提交如果执行逻辑出现了异常那么则会将事务进行回滚。默认情况下会对 RuntimeException 和 Error 进行回滚。可以利用 Transactional 注解中的 rollbackFor 属性进行配置异常信息。
3.1 非public修饰的方法
Transactional 只能用于 public 的方法上否则事务不会生效如果要用在非 public 方法上可以开启 AspectJ 代理模式。
3.2 自身调用
事务的管理是通过代理执行的方式生效的如果是方法内部调用没有经过 Spring 的代理类就调用不到了
3.3 被 final、static 关键字修饰的类或方法
3.4 没有被 Spring 管理
没有注入到IOC容器的的类。
3.5 数据库不支持事务
比如 Mysql 的 Myisam 存储引擎是不支持事务的只有 innodb存储引擎才支持。
3.6 异常被捕获
当异常被捕获后而且没有再抛出那么事务是不会回滚的。
3.7 异常类型错误
Service
public class OrderServiceImpl implements OrderService Transactionalpublic void updateOrder(Order order) {try {// update order} catch {throw new Exception(更新错误);}}
}
这样事务也是不生效的因为默认回滚的是RuntimeException 和 Error如果想触发其他异常的回滚需要在注解上配置一下如通过指定Transactional(rollbackFor Exception.class)的方式进行全异常捕获。
3.8 多线程调用
Spring 的事务是通过数据库连接来实现而数据库连接是放在 ThreadLocal 里面。同一个事务只能用同一个数据库连接。而多线程场景下拿到的数据库连接是不一样的。