spring控制事务的三种方式
首先准备环境,目录结构如下 数据库准备

业务层代码
1 @Service("accountService") 2 public class AccountServiceImpl implements AccountService { 3 @Resource(name = "accountDao") 4 AccountDao accountDao; 5 public void transfer(Integer from, Integer to, Float money) { 6 accountDao.subMoney(from,money); 7 int i = 1/0; //此处引发异常 8 accountDao.addMoney(to,money); 9 } 10 }
持久层代码
1 public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { 2 public void addMoney(Integer id, Float money) { 3 getJdbcTemplate().update("update account set money=money+? where id=?", money , id); 4 } 5 public void subMoney(Integer id, Float money) { 6 getJdbcTemplate().update("update account set money=money-? where id=?", money , id); 7 } 8 }
测试代码
1 @RunWith(SpringJUnit4ClassRunner.class) 2 @ContextConfiguration("classpath:applicationContext.xml") 3 public class Test { 4 @Resource(name="accountService") 5 private AccountService accountService; 6 @org.junit.Test 7 public void test(){ 8 accountService.transfer(1,2,100f); 9 } 10 }
运行结果

现在来用三种方式进行事务控制
方式一:编码方式(需要修改源代码,基本不会用)
添加事务管理类和事务模板类
1 <!-- 事务核心管理器,封装了所有事务操作. 依赖于连接池 --> 2 <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" > 3 <property name="dataSource" ref="dataSource" ></property> 4 </bean> 5 <!-- 事务模板对象 --> 6 <bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" > 7 <property name="transactionManager" ref="transactionManager" ></property> 8 </bean>
修改业务层代码
1 @Service("accountService") 2 public class AccountServiceImpl implements AccountService { 3 @Resource(name = "accountDao") 4 AccountDao accountDao; 5 @Resource(name="transactionTemplate") 6 private TransactionTemplate transactionTemplate; 7 public void transfer(final Integer from, final Integer to, final Float money) { 8 transactionTemplate.execute(new TransactionCallbackWithoutResult() { 9 @Override 10 protected void doInTransactionWithoutResult(TransactionStatus status) { 11 accountDao.subMoney(from,money); 12 int i = 1/0; 13 accountDao.addMoney(to,money); 14 } 15 }); 16 17 } 18 }
方式二:xml配置(不需要改动代码,直接配置xml)
1 <!-- 配置事务通知 --> 2 <tx:advice id="txAdvice" transaction-manager="transactionManager" > 3 <tx:attributes> 4 <!-- 以方法为单位,指定方法应用什么事务属性 5 isolation:隔离级别 6 propagation:传播行为 7 read-only:是否只读 8 --> 9 <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" /> 10 <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /> 11 </tx:attributes> 12 </tx:advice> 13 <!-- 配置织入 --> 14 <aop:config > 15 <!-- 配置切点表达式 --> 16 <aop:pointcut expression="execution(* cn.swun.service.*ServiceImpl.*(..))" id="txPc"/> 17 <!-- 配置切面 : 通知+切点 18 advice-ref:通知的名称 19 pointcut-ref:切点的名称 20 --> 21 <aop:advisor advice-ref="txAdvice" pointcut-ref="txPc" /> 22 </aop:config>
方式三:注解
首先开启注解管理aop事务,然后打注解
1 <!-- 开启使用注解管理aop事务 --> 2 <tx:annotation-driven/>
1 /* 2 * 该注解可以打在方法上,也可以打在类上 3 */ 4 @Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false) 5 public void transfer(final Integer from, final Integer to, final Float money) { 6 accountDao.subMoney(from,money); 7 int i = 1/0; 8 accountDao.addMoney(to,money); 9 }

浙公网安备 33010602011771号