spring中事务失效场景简介说明
下文笔者讲述Spring中事务失效场景说明,如下所示
spring中事务失效场景
一、权限访问问题 二、方法用final修饰 三、无事务嵌套有事务的方法 四、没有被spring管理 五、设计的表不支持事务 六、没有开启事务 七、错误的事务传播 八、自己捕获了异常 九、手动抛出别的异常 十、自定义回滚异常
spring中事务失效场景
一、权限访问问题
当方法不是public的就事务不生效
二、方法用final修饰
spring事务底层实现使用代理 aop,使用jdk的动态代理或cglib 生成代理类 在代理类中实现了事务功能 当方法被final修饰,无法重写该方法,也就无法添加事务的功能
三、无事务嵌套有事务的方法
public void testPrivate() { testFinal(); } @Transactional public void testFinal(){ TbUser build = TbUser.builder().userId(1).userAccount("admin").userPassword("123456") .blogUrl("www.java265.com").remark("欢迎访问").build(); userMapper.insertUser(build); int i = 1 / 0; }
四、没有被spring管理
对象没有被Spring管理 所以@Transactional注解也没有效果哦
五、设计的表不支持事务
数据库不支持事务 如: MySQL使用MyISAM存储引擎
六、没有开启事务
springboot项目 有自动装配的类DataSourceTransactionManagerAutoConfiguration 已经默认开启事务 配置spring.datasource参数就行 如果是spring项目 需在applicationContext.xml配置 不然事务不会生效
七、错误事务传播
使用@Transactional注解时 可指定propagation参数
spring目前支持7种传播特性
REQUIRED 如果当前上下文中存在事务,那么加入该事务 如果不存在事务,创建一个事务,这是默认的传播属性值 SUPPORTS 如果当前上下文存在事务,则支持事务加入事务 如果不存在事务,则使用非事务的方式执行 MANDATORY 如果当前上下文中存在事务,否则抛出异常 REQUIRES_NEW 每次都会新建一个事务,并且同时将上下文中的事务挂起 执行当前新建事务完成以后,上下文事务恢复再执行 NOT_SUPPORTED 如果当前上下文中存在事务,则挂起当前事务 然后新的方法在没有事务的环境中执行 NEVER 如果当前上下文中存在事务,则抛出异常 否则在无事务环境上执行代码 NESTED 如果当前上下文中存在事务,则嵌套事务执行 如果不存在事务,则新建事务
@Transactional(propagation = Propagation.NEVER) public void testFinal(){ TbUser build = TbUser.builder().userId(1).userAccount("admin").userPassword("123456") .blogUrl("www.java265.com").remark("欢迎访问").build(); userMapper.insertUser(build); int i = 1 / 0; }
八、自己捕获了异常
@Transactional public void testFinal(){ TbUser build = null; try { build = TbUser.builder().userId(1).userAccount("admin").userPassword("123456") .blogUrl("www.java265.com").remark("欢迎访问").build(); userMapper.insertUser(build); int i = 1 / 0; } catch (Exception e) { System.out.printf(e.toString()); // throw new RuntimeException(e); } }
在编写事务时,如果我们使用 try catch 捕获了异常 同时没有手动抛出 异常,则事务不生效(因为不抛出异常,Spring不会捕捉到)
九、手动抛出其他异常
@Transactional public void testFinal() throws Exception { TbUser build = null; try { build = TbUser.builder().userId(1).userAccount("admin").userPassword("123456") .blogUrl("www.baidu.com").remark("欢迎访问").build(); userMapper.insertUser(build); int i = 1 / 0; } catch (Exception e) { throw new Exception(e); // throw new RuntimeException(e); } } //上述手动抛出Exception异常 // Spring事务同样不会回滚 由于spring事务 默认情况下不会回滚Exception(非运行时的异常) 只会回滚RuntimeException(运行时异常)和Error(错误)
十、自定义回滚异常
rollbackFor 默认是RuntimeException 和 Error 及子类抛出,就会回滚 如果 rollbackFor 指定异常类型 则只有指定的异常及子类发生才会回滚 @Transactional(rollbackFor = BusinessException.class) public void query(Demo demo) throws Exception{ save(demo); } BusinessException 是我们自定义异常 当这个异常发生的时候才会回滚
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。