`

@Transactional事务控制失效问题

    博客分类:
  • JAVA
 
阅读更多

 我记得当时我遇到这个问题的时候,是因为数据库的表,不支持事务!如果mysql不支持存储引擎,它将以MyISAM表创建表,这是非事务性表。一般修改成InnoDB.

 

假如有兴趣了解mysql中 " engine=innodb " 以及 " engine=innodb和engine=myisam的区别 ",可以读读这篇文章,或许对读者有帮助:http://blog.sina.com.cn/s/blog_6ac4c6cb01018pb1.html

 

可使用下述语句之一检查表的标类型: 

SHOWTABLE STATUS LIKE 'tbl_name';
SHOW CREATETABLE tbl_name;

  使用下述语句,可检查mysqld服务器支持的存储引擎: 

SHOWENGINES;

也可以使用下述语句,检查与你感兴趣的存储引擎有关的变量值: 
SHOWVARIABLES LIKE 'have_%';
  例如,要想确定InnoDB存储引擎是否可用,可检查have_innodb变量的值。

 

在业务代码中,有如下两种情况,比如:
throw new RuntimeException("xxxxxxxxxxxx"); 事务回滚
throw new Exception("xxxxxxxxxxxx"); 事务没有回滚

 

自以为很了解事务,或许时间久远的缘故,没分析出来何故,遂查阅了下资料,写下了如下的内容,供参考:

 

1).Spring的AOP即声明式事务管理默认是针对unchecked exception回滚。也就是默认对RuntimeException()异常或是其子类进行事务回滚;checked异常,即Exception可try{}捕获的不会回滚,如果使用try-catch捕获抛出的unchecked异常后没有在catch块中采用页面硬编码的方式使用spring api对事务做显式的回滚,则事务不会回滚, “将异常捕获,并且在catch块中不对事务做显式提交=生吞掉异常” ,要想捕获非运行时异常则需要如下配置:

解决办法:
1.在针对事务的类中抛出RuntimeException异常,而不是抛出Exception。
2.在txAdive中增加rollback-for,里面写自己的exception,例如自己写的exception:

<tx:advice id="txAdvice" transaction-manager="transactionManager">
   <tx:attributes>
     <tx:method name="*" rollback-for="com.cn.untils.exception.XyzException"/>
   </tx:attributes>
 </tx:advice>

或者
定义不会滚的异常


<tx:advice id="txAdvice">
    <tx:attributes>
       <tx:method name="update*" no-rollback-for="IOException"/>
       <tx:method name="*"/>
    </tx:attributes>
 </tx:advice>


2).spring的事务边界是在调用业务方法之前开始的,业务方法执行完毕之后来执行commit or rollback(Spring默认取决于是否抛出runtime异常).
如果抛出runtime exception 并在你的业务方法中没有catch到的话,事务会回滚。 
一般不需要在业务方法中catch异常,如果非要catch,在做完你想做的工作后(比如关闭文件等)一定要抛出runtime exception,否则spring会将你的操作commit,这样就会产生脏数据.所以你的catch代码是画蛇添足。

如:
try { 
//bisiness logic code 
} catch(Exception e) { 
//handle the exception 

由此可以推知,在spring中如果某个业务方法被一个 整个包裹起来,则这个业务方法也就等于脱离了spring事务的管理,因为没有任何异常会从业务方法中抛出!全被捕获并吞掉,导致spring异常抛出触发事务回滚策略失效。
不过,如果在catch代码块中采用页面硬编码的方式使用spring api对事务做显式的回滚,这样写也未尝不可。

3).基于注解的事务:

Transactional的异常控制,默认是Check Exception 不回滚,unCheck Exception回滚
如果配置了rollbackFor 和 noRollbackFor 且两个都是用同样的异常,那么遇到该异常,还是回滚
rollbackFor 和noRollbackFor 配置也许不会含盖所有异常,对于遗漏的按照Check Exception 不回滚,unCheck Exception回滚

分享到:
评论

相关推荐

    什么情况会导致@Transactional事务失效?

    以下是一些可能导致`@Transactional`事务失效的情况: 1. **未启用事务管理**:如果你的应用没有配置Spring的事务管理器(如PlatformTransactionManager),或者没有开启AOP代理(例如,使用@Component而不是@...

    Java注解@Transactional事务类内调用不生效问题及解决办法

    Java注解@Transactional事务类内调用不生效问题及解决办法 Java注解@Transactional是Java中的一种注解,主要用于标记事务边界。然而,在某些情况下,@Transactional注解可能不会生效,例如在同一个类中的方法调用...

    Spring @Transactional注解失效解决方案

    本篇文章将详细介绍 @Transactional 注解失效解决方案,通过示例代码和详细的解释,帮助开发者解决 @Transactional 注解失效的问题。 一、了解 @Transactional 注解的特性 在了解解决方案之前,我们首先需要了解 @...

    详细整理Spring事务失效的具体场景及解决方案.docx

    Spring事务失效的常见场景有七种,分别是:注解@Transactional 配置的方法非 public 权限修饰、注解@Transactional 所在类非 Spring 容器管理的 bean、注解@Transactional 所在类中,注解修饰的方法被类内部方法调用...

    Spring事务管理失效原因汇总

    描述部分进一步说明了事务失效的后果往往不明显,容易在测试环节被忽略,但在生产环境中出现问题,暴露了开发者对Spring事务机制不足够了解的问题。标签“Spring 事务 失效”直接概括了本文的知识点范围,即Spring...

    Spring的事务10种常见失效场景总结.zip

    1. **未开启事务**:如果在需要事务控制的方法中忘记添加`@Transactional`注解,Spring将不会自动进行事务管理,导致事务失效。记得在服务层方法上正确使用该注解,确保事务开始和结束。 2. **切面配置错误**:在...

    Spring事务不生效.pdf

    本文将深入探讨Spring事务失效的常见原因,帮助开发者识别并解决这些问题。 首先,我们要明白Spring事务的工作原理。Spring采用AOP(面向切面编程)来实现事务管理,通过动态代理在方法执行前后插入事务处理逻辑。...

    spring05-6

    在描述中的问题中,开发者可能没有在服务层的方法上正确地使用`@Transactional`注解,或者事务配置可能不正确,导致错误发生后事务没有回滚。为了解决这个问题,我们需要确保以下几点: 1. **启用事务管理**:在...

    spring事务总结.docx

    然而,在实际开发过程中,经常会遇到一些关于Spring事务的问题,如事务失效、事务回滚、大事务问题以及编程式事务等。本文将深入探讨这些问题,并给出相应的解决方案。 #### 一、事务不生效的原因及解决办法 1. **...

    springtransaction 事务管理

    声明式事务管理依赖于Spring的AOP机制,它可以在不修改业务代码的情况下,通过代理对象拦截方法调用,实现事务的自动控制。AOP允许我们定义“切面”(Aspect),即关注点的模块化,如事务管理就是一个典型的横切...

    SSM中事务管理所需的jar包-aspectjweaver

    8. **注意事项**:虽然AspectJ事务管理方便,但需要正确配置并理解其工作原理,否则可能导致事务管理失效或产生意外的结果。此外,由于其运行时编织的特性,可能会带来一定的性能影响。 总结起来,`aspectjweaver....

    Spring Boot + Druid + Mybatis + Atomikos 配置多数据源 并支持分布式事务

    5. 编写业务代码:在服务层,使用@TransactionManagement注解开启事务管理,并在方法上使用@Transactional注解定义事务边界。 在实际应用中,需要注意以下几点: - 数据源切换:使用AOP或者ThreadLocal等技术,根据...

    解决osgi spring 事务配置问题

    首先,Spring的事务管理主要依赖于AOP(面向切面编程)来实现,通过定义事务边界,如`@Transactional`注解,来控制事务的开始、提交、回滚等行为。但在OSGi中,由于类加载器的隔离,Spring的代理机制可能会失效,...

    chap05.rar 配置关于数据库事务介绍的博文

    例如,使用c3p0时,需要配置c3p0的数据源bean,然后配置PlatformTransactionManager,最后在需要事务控制的方法上添加@Transactional注解。类似地,对于dbcp2和HikariCP,也有对应的配置步骤。 了解和掌握数据库...

    解决springboot的aop切面不起作用问题(失效的排查)

    在SpringBoot中,我们可以使用`@Transactional`注解来实现事务。例如: ```java @Service public class MyService { @Transactional public void doSomething() { // ... } } ``` 默认情况下,`@Transactional...

    多数据源事务jta测试

    - **Spring框架的支持**:Spring提供了声明式事务管理,简化了JTA的使用,通过`@Transactional`注解可以轻松地开启和管理事务。 测试环节可能会涉及到创建单元测试和集成测试,确保在各种情况下事务都能正确处理。...

    这一次搞懂Spring事务注解的解析方式

    - 没有正确处理异常:未检查异常和受检查异常的处理不当可能导致事务失效。 通过理解这些核心概念和机制,我们可以更深入地掌握Spring事务注解的工作原理,避免在实际开发中遇到不必要的问题。

    springAop事务配置

    - 对于异步方法,需要额外注意事务边界,因为线程切换可能导致事务管理失效,可能需要使用异步事务支持。 5. **注意事项** - 事务管理需要与Spring容器协同工作,因此使用事务管理时,需要确保Spring能管理相关的...

    Spring框架是在2003年兴起的一门轻量级的JAVAEE框架技术 Spring框架学习资料第五天

    **一、事务传播属性失效问题及解决** 事务传播属性在Spring中用于控制事务边界,但有时可能会遇到配置无效的情况。解决思路是确保从Spring工厂中获取到的是代理类对象,因为事务管理是通过AOP(面向切面编程)实现的...

Global site tag (gtag.js) - Google Analytics