如何免费建设网站免费logo设计在线生成器官网
news/
2025/10/2 23:05:04/
文章来源:
如何免费建设网站,免费logo设计在线生成器官网,免费做h5的网站知乎,培训机构贴一篇源码分析的好文章#xff1a;https://blog.csdn.net/qq_30905661/article/details/114400417
本质#xff1a;
一个事务对应一个数据库连接。 通过 this 来调用某个带有 Transactional 注解的方法时#xff0c;这个注解是失效的#xff0c;可以看做这个方法#x…贴一篇源码分析的好文章https://blog.csdn.net/qq_30905661/article/details/114400417
本质
一个事务对应一个数据库连接。 通过 this 来调用某个带有 Transactional 注解的方法时这个注解是失效的可以看做这个方法如上图B上没有这个注解当然书写的传播机制限制也是无效的例如propagation Propagation.MANDATORY、propagation Propagation.NEVER。 但是若调用A的是CGLIB生成的代理对象并且A上有 Transactional 注解那么方法A是具有事务的方法B中的sql 就在方法A的事务中执行所以整体AB是有事务的。
Spring的事务是如何实现的
spring事务底层是通过数据库事务和AOP实现的首先对于使用Transactional的注解的beanspring会创建一个代理对象作为bean当调用代理对象的方法时spring会判断该方法上是否加了Transactional注解如果加了就会利用事务管理器创建一个数据库连接并修改数据库连接的 autocommit 为 false禁止自动提交然后执行该方法若方法没有抛异常则会提交事务反之亦然spring事物的隔离级别就是对应数据库的隔离级别spring事务的传播机制是spring自己实现的是spring事务中最复杂的spring事物的传播机制是基于数据库连接来做的一个连接一个事务传播事务实际上是开了一个新的数据库连接在此基础上执行sql
Spring事物的传播机制
spring事务默认是注解是 REQUIRED支持事务的传播使用同一个数据库连接。
REQUIREDspring默认的事务传播机制A存在事务则B加入A的事务A没有事务则会新建一个数据库事务
SUPPORTS支持当前事务如果当前存在事务就加入该事务如果当前不存在事务就以非事务执行
MANDATORY强制性使用第一个事务A存在事务则B加入A的事务A没有事务则抛异常
REQUIRES_NEW创建一个新事务B在这个新事务中执行A如果有事务将会被挂起等待B事务方法执行结束commit or rollback当B事务执行结束后A事务被唤醒继续执行若B抛出了异常给A 或 A 方法执行出了异常那么在 A 事务中执行的 sql 将会被回滚B 事务中的sql 由B的事务管理器控制A、B中的sql不在同一数据库连接中执行即内层事务B已经 commit 或 rollback 外层事务干扰不了。
NOT_SUPPORTED不支持事务若A存在事务则挂起A的事务以非事务方式运行
NEVER不支持事务若A存在事务抛异常
NESTEDA存在事务则在嵌套事务中执行不存在则和 REQUIRED 一样开启一个新事务
那些情况会导致Spring事务的失效失效的原因是 数据库不支持事务 类没有被spring管理ioc没有加注解。 未启用Spring事务管理功能EnableTransactionManagement 数据源没有配置事务管理器 Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){return new DataSourceTransactionManager(dataSource);
}没有加Configuration注解springboot基本没有这个问题Spring可能会出现这个问题原因是由于mybatis或JdbcTemplate会从ThreadLocal中获取数据库连接但是ThreadLocal底层引用的是ThreadLocalMapMap的key是一个DataSource对象value是数据库连接。如果没有加Configuration注解的话会导致Map中的DataSource对象和mybatis、jdbcTenplate中的DataSource对象不相等所有就拿不到数据库连接以至于自己去创建连接了。 异常被吃掉默认情况下Spring会捕获 error 和 RunTimeException spring捕获不到异常也就不会回滚了例如 try-catch 方法是private的spring事务基于CGLIB来进行AOPCGLIB是基于父子类来实现子类是代理类子类无法重写父类的private方法也就没有办法增加spring事务逻辑。 方法是 final 修饰的和private原因一致子类不能重写增强。 调用A方法和B方法不是同一个线程不同的线程拿到的数据库连接不一样。TransactionSynchronizationManager.bindResource 会将线程与数据库连接绑定。 rollbackFor RuntimeException.class默认当抛出的异常大于定义的异常则会导致事务失效 方法内自调用时对象不是同一个Spring事务是基于Aop只有使用代理对象调用 A 方法时注解才能生效而在A方法中调用 B 方法时 this.B() 并不是使用的代理对象所以导致B的注解失效。
自身调用失效问题
方法A 通过 this.B() 调用方法B。 本质通过 this 来调用某个带有 Transactional 注解的方法时这个注解是失效的可以看做这个方法如上图B上没有这个注解当然书写的传播机制限制也是无效的例如propagation Propagation.MANDATORY、propagation Propagation.NEVER。 但是若调用A的是CGLIB生成的代理对象并且A上有 Transactional 注解那么方法A是具有事务的方法B中的sql 就在方法A的事务中执行所以整体AB是有事务的。
调用使用Transactional注解的方法时使用的是 Spring CGLIB 创建的代理对象
调用B方法的是存储在 Spring ioc容器的bean两个不同的对象
A调用B的结论
只要A加Transactional注解A和B在不在同一个类中B加不加Transactional注解事务都是有效的则AB在同一事务中。A 不加 B加A和B同一个类中调用A方法的是CGLIB生成的代理对象但是A方法没有注解所以A方法不会被拦截this调用B注解失效下图。A 不加 B加A和B不在同一个类中不在同一个类那么调用B的就是的就是CGLIB生成的代理对象B的事务有效A在外围没有事务B已经commit或rollback了事务管理器已经把设置auto commit false的数据库连接释放了。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/925398.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!