一、编程式事务
1、基于底层API
通过TransactionDefinition、TransactionStatus、PlatformTransactionManager核心接口。
给数据源添加事务管理。
`<!-- 为数据源添加事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>`
事务定义、开启、提交。
// 默认事务定义,例如隔离级别、传播行为等
TransactionDefinition tf = new DefaultTransactionDefinition();
// 开启事务
TransactionStatus ts = txManager.getTransaction(tf);
// 提交事务
txManager.commit(ts);
2、基于TransactionTemplate
给数据源添加事务管理。
<!-- 为数据源添加事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 为事务管理器添加事务模板 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="txManager"/>
</bean>
通常以匿名内部类的方式实现TransactionCallback接口,其execute方法有一个TransactionCallback接口类型参数,该接口中定义了一个doInTransaction方法用于编写逻辑代码。其TransactionStatus参数的setRollbackOnly方法将事务标记为回滚。
transactionTemplate.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus status) {
}
});
二、声明式事务
1、基于XML
Spring框架提供了tx命名空间来配置事务。
tx:advice元素配置事务通知时,一般需指定id和transaction-manager属性。
tx:attributes指定执行事务的细节。
<!-- 为数据源添加事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 编写通知声明事务 -->
<tx:advice id="myAdvice" transaction-manager="txManager">
<tx:attributes>
<!-- *表示任意方法 -->
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- 编写AOP,让spring自动对目标对象生成代理,需要使用aspectj的表达式 -->
<aop:config>
<!-- 定义切入点 -->
<aop:pointcut expression="execution(* transaction.declaration.xml.service.impl.*.*(..))" id="txPointCut"/>
<!-- 切面:将切入点与通知关联 -->
<aop:advisor advice-ref="myAdvice" pointcut-ref="txPointCut"/>
</aop:config>
2、基于@Transactional
该注解可用于接口、类、方法上。作用于类上时,该类的所有public方法都具有该类型事务属性。
<!-- 为数据源添加事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 为事务管理器注册注解驱动器 -->
<tx:annotation-driven transaction-manager="txManager"/>
注:
1,、不推荐注解到接口或接口方法上。因为只有使用基于接口的代理时才生效。2、@Transactional指定类需要受Spring的事务管理,只能针对public属性范围内的方法添加。
3、逻辑代码中有try-catch语句,则不能正常回滚。
因为默认情况下,spring只在发生未被捕获异常的RuntimeException时才回滚事务。
方法一、此时需要rollback-for指定回滚生效的异常类,多个异常类用逗号分隔。no-rollback-for指定回滚失效的异常类。
<tx:method name="*" rollback-for = "java.lang.Exception"/>
@Transactional(rollbackFor = { Exception.class })
方法二、直接在catch中添加下列语句即可
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();