spring事物失效

一、spring父子容器读取spring bean的配置文件出现事物无效

spring父容器通过 contextLoaderListener启动,加载web.xml 中的<context-param>内容,子容器通过web.xml内配置的servlet启动,加载servlet配置下的<init-param>内容,spring 的扫描组件的配置文件(有context:component-scan标签)通过子容器来加载的话,各种组建会在子容器中实例化成bean,但是父子容器的访问权限是子可以访问父,父不能访问主,而spring事物原理是通过拦截目标方法(xml中aop配置或者打上@Transactional注解的方法),在方法开始前添加开启事物语句,方法末尾添加事物提交语句,整个方法抛出运行时异常(默认是运行时异常,可以通过配置修改其他异常)后事物回滚,这类需要事物管理的目标方法一般在service类中,有@service注解,但是事物编织过程可能在父容器中进行(事务管理器配置通过父容器读取),如果service是在子容器中生成bean,那给service方法编织事物管理的时候父容器是获取不到service实例的,所以当service实例注入到controller层的时候没有事物能力,也就出现之前配置好的spring事物配置或者明明service的方法打上@transactional注解,事物却不起作用。解决办法是要么所有配置文件全通过父容器加载,要么全部通过子容器加载。
二、事物编织(通过xml的aop配置或者注解标注)的方法内无异常抛出,或者抛出的异常不是运行时异常。

spring 事务无效解决方法(事物编织的方法内无异常抛出,或者抛出的异常不是运行时异常)

(原)

spring 事务目前有二种,声明式(declarative transaction)和编程式(programming transaction),以前都是以公司里的框架写好的,没有学习的机会,今天抽空好好试了下,结果遇到好多问题。

1、注解的方式

spring事物失效

spring事物失效

最开始是这么玩的,发现数据进数据库了,没有起作用,然后各种搜索,终于找到问题了,在@Transactional中,默认只有抛出运行时异常才会回滚,也就是说throw new RuntimeException();而我这里是Exception。

在spring的文档中说道,spring声明式事务管理默认对非检查型异常和运行时异常进行事务回滚,而对检查型异常则不进行回滚操作。

在这里,RuntimeException是非检查型异常,Exception是检查型异常

这里有二种解决办法,1、将Exception类改为RuntimeException类抛出,2、将@Transactional注解改为@Transactional(rollbackFor = Exception.class),也就是说检查型异常一样回滚。二种改法结果测试都通过。

2、配置XML(需要aspectj的支持)

由于是在网上找的例子建的ssm框架,例子中并没有事务,所以才需要添加,注解的方式成功后,下面来试试声明式的,结果一上来就发现报错

spring事物失效

 

 spring事物失效

网上搜了一下,发现是少jar包引起的

ava.lang.NoClassDefFoundError:org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException

缺少的两个jar包:aspectjrt.jar;aspectjweaver.jar ,这是springAOP所依赖的包

加进这二个JAR包以后,启动成功。

跟注解式的一样,抛出Exception异常数据一样进数据库,而抛出RuntimeException异常成功回滚,然后在tx:method中一样找到了rollback-for的属性,加上去后,Exception异常也能成功回滚了

spring事物失效

 3、 Spring的AOP中,XML注入TransactionProxyFactoryBean这个类