Spring Transaction
spring中的事务管理方式:
- 编程式事务管理
声明式事务管理
说明: 此处只是用的一些xml配置及其service实现,其他DAO层及测试都是跟上一篇文章一样
1、编程式事务管理
编程式事务管理 主要是通过TransactionTemplate类的execute方法来实现事务特性的:
org.springframework.transaction.support.TransactionTemplate
1、首先 在XML中配置 TransactionTemplate
<!-- 编程式事务管理 -->
<!-- 用于 编程式 事务管理模板 -->
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager" />
</bean>
2、在service中添加成员变量TransactionTemplate
package com.wm.spring.tx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
@Service
public class AccountProgramSVImpl {
@Autowired
private TransactionTemplate transactionTemplate ;
@Autowired
private AccountDAO dao ;
public void doProgrammationTransaction(final String accA , final String accB, final int money){
// 要实现 事务特性 的代码放入其中
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus arg0) {
dao.income(accA, money); //A的余额增加
dao.spend(accB, money); //B的余额减少
}
});
}
}
执行transactionTemplate.execute(),方法体为一个内部类TransactionCallbackWithoutResult,在此类在实现方法:doInTransactionWithoutResult -- 此方法体 中写入 要实现事务特性的代码块。
方法中写入的 代码、方法,则具有事务特性。
由此可以发现:编程式事务管理方式,对于不同的具有事务特性的业务都要实现 transactionTemplate.execute(),所以毕竟冗余。
2、声明式事务管理 – 基于aspectJ XML形式
实则就是 使用AOP来实现事务管理。
1、首先配置XML
<!-- 声明式事务管理 2 -->
<!-- 声明式事务管理 之 基于AspectJ XML形式 -->
<!-- 配置事务的通知(事务的增强) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes >
<!-- 配置 方法 及其 它的 事务属性 -->
<tx:method name="xmlAnnotationTransfer" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- AOP的切面 -->
<aop:config >
<!-- 表达式 execution() -->
<aop:pointcut expression="execution(* com.wm.spring.tx.AccountXmlSVImpl.*(..))" id="pointCut" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>
<bean id="accountXmlDAO" class="com.wm.spring.tx.AccountXmlDAO">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
<bean id="accountXmlSVImpl" class="com.wm.spring.tx.AccountXmlSVImpl">
<property name="dao" ref="accountXmlDAO" />
</bean>
2、service
package com.wm.spring.tx;
public class AccountXmlSVImpl {
private AccountXmlDAO dao;
public void xmlAnnotationTransfer(String acctA, String acctB, int money){
dao.income(acctA, money);
dao.spend(acctB, money);
}
public AccountXmlDAO getDao() {
return dao;
}
public void setDao(AccountXmlDAO dao) {
this.dao = dao;
}
}
则此 方法xmlAnnotationTransfer 配置了事务增强,此方法就具有事务特性。
3、声明式事务 – 基于TransactionProxyFactoryBean
使用 基于TransactionProxyFactoryBean 来对 目标类 实现 事务 增强
1、XML配置
<!-- 声明式事务管理 1 -->
<!-- 声明式事务管理 之 -基于TransactionProxyFactoryBean 来对 目标类 实现 事务 增强 -->
<bean id="transactionProxyFactoryBean"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="target" ref="accountXmlSVImpl" />
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<!-- key:填写要具有 事务特性的方法 value:填写事务属性 多个属性之间用逗号 ,隔开 -->
<prop key="xmlAnnotationTransfer">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
经过TransactionProxyFactoryBean类来增强事务,目标类accountXmlSVImpl中配置了的方法,则具备事务特性。
4、propagation
spring 中事务的传播行为propagation:就是当多个事务嵌套、并发执行时,按照每种方式来执行。
- PROPAGATION_REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
- PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
- PROPAGATION_MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。
- PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。 - PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 - PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。 - PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
spring中最常用的传播行为是REQUIRED 和 REQUIRES_NEW两种。