一、注解事务的使用:
<!-- 数据源 --> <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <property name="driverClassName" value="${db.driverClassName}" /> <property name="url" value="${db.url}" /> <!-- 相关配置 --> </bean> <!-- 事务配置 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean><!-- 没有指定 proxy-target-class="true" 则默认spring会自动挑选jdk代理或cglib代理。--><tx:annotation-driven transaction-manager="transactionManager" /> <!-- 扫描注解 --> <context:component-scan base-package="com.thunder.practice" />
关于@Transactional的添加位置:
当使用jdk代理的时候,由于是基于接口的代理,此时可以将@Transactional放到接口定义,或接口方法上,所有继承该接口的类、方法,都将继承事务。也可以放到实现类的类定义或者某个方法上。
当使用cglib代理的时候,由于是基于类的代理,此时如果将@Transactional放到接口定义,或接口的方法上,则此时事务将失效,但不会抛异常。
因此建议将@Transactional的注解放在实现类的类定义或者具体方法之上。另外在方法上的@Transactional注解会覆盖掉类上的注解。
ps.还有一种常见的事务失效的错误:
sprign mvc+spring 的项目结构时,如果分成两个配置文件,一个由spring mvc的配置文件(由dispatcher servlet调用的配置文件)和spring的配置文件(由listener调用的配置文件)是不同的上下文对象(父子上下文,父子容器)。spring配置文件属于父上下文,里面定义了事务管理,事务管理是有这个上下文控制的,mvc配置文件属于子上下文,一般会把扫描注解的配置放到mvc配置文件,此时mvc的上下文扫描到的Service是没有经过事务加强的service,(ps.事务管理的本质是AOP增强处理),所以事务没有生效,也不会报错。
解决办法是将事务管理和扫描@Transactional注解进行增强的配置放在一个上下文就行了。
二、事务的隔离级别和传播方法
时间: 2024-09-29 06:01:04