spring的两种常用事务传播REQUIRED和REQUIRES_NEW

看了网上的培训机构的视频,说了事务传播机制,云里雾里的,TM的还说错了,说的乱七八糟,念课本呢,也没实例,做个毛的培训!!!

事务的实现方式有两种:一种是编程式和声明式。编程式是开发自己控制,比如自己rollback、commit,其实也是调用数据库的事务接口。
声明式就是@Transational开启事务 ,也就是一种AOP实现,生成代理对象,在方法上提交和回滚。默认对RuntimeException和Error回滚,也可以指定异常类型进行回滚。

事务的隔离级别(由低到高):
read uncommitted(一个事务没提交,另一个事务可以读到)
read committed(一个事务提交了,另一个事务才能读到)--在spring中oracle的默认
repeatable read (可重复度)--在spring中mysql的默认级别
serializable(可串行化)


问题1:在spring种如果不加事务@Transactional会怎么样呢?

Controller有两个service,第二个service有插入操作,插入完后运行后面的代码报错了,那么数据库已经提交了数据,造成事务不一致。

解决方法:只要在第二个service里的方法加上@Transactional,这样第二个service中的操作就会回滚。

但是呢?第一个service还是提交了!!

解决:如果第一个service也加上Transational 。

问题2:结果第一个service还是提交了!!!为什么呢,个人理解因为在两个service里是两个不同的事务,因此会提交第一个没报错的service

解决:controller上也加上@Transactional,把这两个service纳入到一个事务里。

问题3:controller中有@Transactional,service1没@Transactional,service2加上@Transactional,这时候service2报错,那service1会提交吗?

不会提交,因为controller上有@Transactional,service1和service2都会纳入事务。

问题4:controller中有@Transactional,如果想让service1提交,service2报错回滚怎么做?

controller加@Transactional,service1加@Transactional(propagation = Propagation.REQUIRES_NEW),servcie2加@Transactional

spring常用的两种传播属性

1.REQUIRED 如果存在当前事务则用当前事务,如果不存在当前事务,则新建一个事务

2.REQUIRES_NEW 如果当前存在事务则挂起当前事务,开启一个新事务,新事务执行完毕后,唤醒之前挂起的事务,继续执行。如果不存在当前事务,则新建一个事务。

spring默认是REQUIRED ,就是要么一起成功,要么一起失败。

REQUIRES_NEW  (培训机构的老师都说错了,真坑!!!)我的理解就是开启一个独立事务,也就是说当前@Transational内没报错,就会提交。

Controller的方法上加上@Transactional注解

MyService: REQUIRES_NEW 开启新的事务

MyService2:默认事务传播机制

Mapper

http://127.0.0.1:8080/in/0

结果:myService插入数据成功,myService2回滚

注意:

1.controller层也要加@Transactional,否则不起作用

参考资料:https://blog.csdn.net/qianxiaopeng/article/details/82427689

猜你喜欢

转载自blog.csdn.net/x18094/article/details/115290933