首页 > 代码库 > Spring事务

Spring事务

一、Spring事务接口

spring事务提供了三个主要的接口PlatformTransactionManager、TransactionDefination定义事务隔离级别、TransactionDefination定义事务传播行为、TransactionStatus接口。

PlatformTransactionManager:事务管理器。

TransactionDefination:定义事务隔离级别:READ_UNCOMMITED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE。mysql数据库默认的是REPEATABLE_READ级别4.

TransactionDefination:定义事务传播行为:PROPAGATION_REQUIRED、PROPAGATION_SUPPORTS、PROPAGATION_MANDATORY、PROPAGATION_REQUIRES_REW、PROPAGATION_NOT_SUPPORTED、PROPAGATION_NEVER、PROPAGATION_NESTED

二、spring事务管理--转账案例

2.1、环境搭建

    引入相关jar包、jdbc.properties、log4j.properties等

    AccountService接口、AccountServiceImpl实现类

    AccountDao接口、AccountDaoImpl实现类

AccountService.java接口

  1: package com.spring.demo1;
  2: 
  3: public interface AccountService {
  4:   public void transfer(String OutName,String InName,Double money);
  5: }
  6: 

AccountDao.java接口:

  1: package com.spring.demo1;
  2: public interface AccountDao {
  3:   public void outMoney(String OutName,Double money);
  4:   public void inMoney(String InName,Double money);
  5: }
  6: 

AccountDaoImpl.java

  1: package com.spring.demo1;
  2: 
  3: import org.springframework.jdbc.core.support.JdbcDaoSupport;
  4: public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao  {
  5: 
  6:   public void inMoney(String InName, Double money) {
  7:     // TODO Auto-generated method stub
  8:     String sql="update account set money=money + ? where name= ?";
  9:     this.getJdbcTemplate().update(sql,money,InName);
 10:   }
 11: 
 12:   public void outMoney(String OutName, Double money) {
 13:     // TODO Auto-generated method stub
 14:     String sql="update account set money=money - ? where name= ?";
 15:     this.getJdbcTemplate().update(sql,money,OutName);
 16:   }
 17: 
 18: }
 19: 

 

2.2、编程式事务管理

ApplicationContex.xml

  1: <?xml version="1.0" encoding="UTF-8" ?>
  2: <beans xmlns="http://www.springframework.org/schema/beans"
  3:   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
  4:   xmlns:context="http://www.springframework.org/schema/context"
  5:   xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  6:   xsi:schemaLocation="http://www.springframework.org/schema/beans 
  7:        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  8:        http://www.springframework.org/schema/context 
  9:        http://www.springframework.org/schema/context/spring-context-3.0.xsd
 10:        http://www.springframework.org/schema/tx 
 11:        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
 12:        http://www.springframework.org/schema/aop
 13:        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 14:     
 15:     
 16:    <!-- 引入外部的属性文件 -->
 17:   <context:property-placeholder location="classpath:jdbc.properties" />
 18:      
 19:      <!-- 配置c3p0连接池 
 20:   <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
 21:     p:driverClass="${jdbc.driverClass}"
 22:     p:jdbcUrl="${jdbc.url}"
 23:     p:user="${jdbc.username}"
 24:     p:password="${jdbc.password}" />-->
 25:   
 26:   <!-- 配置dbcp连接池 -->
 27:   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
 28:     destroy-method="close" 
 29:     p:driverClassName="${jdbc.driverClass}"
 30:     p:url="${jdbc.url}"
 31:     p:username="${jdbc.username}"
 32:     p:password="${jdbc.password}" />
 33: 
 34:   <!-- 配置Jdbc模板  -->
 35:   <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
 36:     p:dataSource-ref="dataSource" />
 37:   
 38:   <!-- 业务层 -->
 39:   <bean id="accountService" class="com.spring.demo4.AccountServiceImpl" p:accountDao-ref="accountDao"/>
 40: 
 41:   <!-- Dao类 -->
 42:   <bean id="accountDao" class="com.spring.demo4.AccountDaoImpl" p:dataSource-ref="dataSource" />
 43:   
 44:   <!-- 配置事务管理器 -->
 45:   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" 
 46:     p:dataSource-ref="dataSource" />
 47:   
 48:   <!-- 定义一个事务管理模板 :spring为了简化事务管理的代码而提供的类-->
 49:   <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"
 50:     p:transactionManager-ref="transactionManager" />
 51:   
 52: </beans>
 53: 

AccountServiceImpl.java

  1: package com.spring.demo1;
  2: 
  3: import org.springframework.transaction.TransactionStatus;
  4: import org.springframework.transaction.support.TransactionCallback;
  5: import org.springframework.transaction.support.TransactionCallbackWithoutResult;
  6: import org.springframework.transaction.support.TransactionTemplate;
  7: import com.sun.istack.internal.FinalArrayList;
  8: public class AccountServiceImpl implements AccountService {
  9: 
 10:   //注入转账的DAO类
 11:   
 12:   private AccountDao accountDao;
 13:   public void setAccountDao(AccountDao accountDao) {
 14:     this.accountDao = accountDao;
 15:   }
 16:   
 17:   //注入事务管理的模板
 18:   private TransactionTemplate transactionTemplate;
 19:   public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
 20:     this.transactionTemplate = transactionTemplate;
 21:   }
 22:   
 23:   public AccountDao getAccountDao() {
 24:     return accountDao;
 25:   }
 26: 
 27:   public TransactionTemplate getTransactionTemplate() {
 28:     return transactionTemplate;
 29:   }
 30: 
 31:   public void transfer(final String OutName,final String InName,final Double money) {
 32:     // TODO Auto-generated method stub
 33:     transactionTemplate.execute(new TransactionCallbackWithoutResult() {      
 34:       @Override
 35:       protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
 36:         // TODO Auto-generated method stub
 37:         accountDao.outMoney(OutName, money);
 38:         accountDao.inMoney(InName, money);
 39:       }
 40:     });
 41:   
 42:   }
 43: 
 44: }
 45: 

测试类:springtestdemo1.java

  1: package com.spring.demo1;
  2: 
  3: import javax.annotation.Resource;
  4: import org.junit.Test;
  5: import org.junit.runner.RunWith;
  6: import org.springframework.test.context.ContextConfiguration;
  7: import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  8: @RunWith(SpringJUnit4ClassRunner.class)
  9: @ContextConfiguration("classpath:applicationContext.xml")
 10: public class springtestdemo1 {
 11:   //测试业务层类:
 12:   @Resource(name="accountService")
 13:   private AccountService accountService;
 14:   @Test
 15:   public void demo1(){
 16:     accountService.transfer("aaa", "bbb", 200d);
 17:   }
 18: }
 19: 

运行结果:

技术分享 技术分享

当修改一下AccountServiceImpl.java的代码

  1: accountDao.outMoney(OutName, money);
  2: int i=1 / 0;
  3: accountDao.inMoney(InName, money);

当不引入事务管理的运行结果: 发现用户aaa已经少了300块,但是用户bbb却没有增加.

技术分享 技术分享

当引入事务管理的运行结果: 这时候,用户aaa和bbb不会出现不一致的情况

技术分享 技术分享

 

2.3、声明式事务管理方式一:TransactionProxyFactoryBean

ApplicationContext2.xml

  1: <?xml version="1.0" encoding="UTF-8" ?>
  2: <beans xmlns="http://www.springframework.org/schema/beans"
  3:   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
  4:   xmlns:context="http://www.springframework.org/schema/context"
  5:   xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  6:   xsi:schemaLocation="http://www.springframework.org/schema/beans 
  7:        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  8:        http://www.springframework.org/schema/context 
  9:        http://www.springframework.org/schema/context/spring-context-3.0.xsd
 10:        http://www.springframework.org/schema/tx 
 11:        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
 12:        http://www.springframework.org/schema/aop
 13:        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 14:     
 15:    <!-- 引入外部的属性文件 -->
 16:   <context:property-placeholder location="classpath:jdbc.properties" />
 17:      
 18:      <!-- 配置c3p0连接池 
 19:   <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
 20:     p:driverClass="${jdbc.driverClass}"
 21:     p:jdbcUrl="${jdbc.url}"
 22:     p:user="${jdbc.username}"
 23:     p:password="${jdbc.password}" />-->
 24:   
 25:   <!-- 配置dbcp连接池 -->
 26:   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
 27:     destroy-method="close" 
 28:     p:driverClassName="${jdbc.driverClass}"
 29:     p:url="${jdbc.url}"
 30:     p:username="${jdbc.username}"
 31:     p:password="${jdbc.password}" />
 32: 
 33:   <!-- 配置Jdbc模板  -->
 34:   <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
 35:     p:dataSource-ref="dataSource" />
 36:   
 37:   <!-- 业务层 -->
 38:   <bean id="accountService" class="com.spring.demo4.AccountServiceImpl" p:accountDao-ref="accountDao"/>
 39: 
 40:   <!-- Dao类 -->
 41:   <bean id="accountDao" class="com.spring.demo4.AccountDaoImpl" p:dataSource-ref="dataSource" />
 42:   
 43:   <!-- 配置事务管理器 -->
 44:   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" 
 45:     p:dataSource-ref="dataSource" />
 46:   
 47:   <!-- 配置业务层的代理 -->
 48:         <!-- prop的格式:
 49:             PROPAGATION:事务的传播行为
 50:             ISOLATION : 事务的隔离级别
 51:             readOnly:   只读
 52:             -Exception :发生哪些异常,回滚事务
 53:             +Exception:发生哪些异常,事务不回滚
 54:          -->
 55:   <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
 56:     <!-- 配置目标对象 -->
 57:     <property name="target" ref="accountService" />
 58:     <!-- 事务事务管理器 -->
 59:     <property name="transactionManager" ref="transactionManager" />
 60:     <!-- 注入事务的一些属性 -->
 61:     <property name="transactionAttributes" >
 62:       <props>
 63:         <prop key="transfer">PROPAGATION_REQUIRED,+java.lang.ArithmeticException</prop>
 64:       </props>
 65:     </property>
 66:   </bean>  
 67: </beans>

AccountServiceImpl.java

  1: package com.spring.demo2;
  2: import org.springframework.transaction.TransactionStatus;
  3: import org.springframework.transaction.support.TransactionCallback;
  4: import org.springframework.transaction.support.TransactionCallbackWithoutResult;
  5: import org.springframework.transaction.support.TransactionTemplate;
  6: import com.sun.istack.internal.FinalArrayList;
  7: public class AccountServiceImpl implements AccountService {
  8:   //注入转账的DAO类  
  9:   private AccountDao accountDao;
 10:   public void setAccountDao(AccountDao accountDao) {
 11:     this.accountDao = accountDao;
 12:   }    
 13:   public void transfer(String OutName, String InName, Double money) {
 14:     // TODO Auto-generated method stub
 15:     accountDao.outMoney(OutName, money);
 16:     int i=1/0;
 17:     accountDao.inMoney(InName, money);  
 18:   }
 19: }
 20: 

测试类:springtestdemo2.java

  1: package com.spring.demo2;
  2: import javax.annotation.Resource;
  3: import org.junit.Test;
  4: import org.junit.runner.RunWith;
  5: import org.springframework.test.context.ContextConfiguration;
  6: import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  7: /**
  8:  * 声明式
  9:  * 
 10:  * @author su
 11:  *
 12:  */
 13: @RunWith(SpringJUnit4ClassRunner.class)
 14: @ContextConfiguration("classpath:applicationContext2.xml")
 15: public class springtestdemo2 {
 16:   //测试业务层类:
 17:   /**
 18:    * 
 19:    * 注入代理类:因为代理类已经增强了
 20:    */
 21:   //@Resource(name="accountService")
 22:   @Resource(name="accountServiceProxy")
 23:   private AccountService accountService;
 24:   @Test
 25:   public void test(){
 26:     accountService.transfer("aaa", "bbb", 300d);
 27:   }
 28: }

运行结果图上。

2.4、声明式事务管理方式二:基于AspectJ的xml配置

ApplicationContex3.xml

  1: <?xml version="1.0" encoding="UTF-8" ?>
  2: <beans xmlns="http://www.springframework.org/schema/beans"
  3:   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
  4:   xmlns:context="http://www.springframework.org/schema/context"
  5:   xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  6:   xsi:schemaLocation="http://www.springframework.org/schema/beans 
  7:        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  8:        http://www.springframework.org/schema/context 
  9:        http://www.springframework.org/schema/context/spring-context-3.0.xsd
 10:        http://www.springframework.org/schema/tx 
 11:        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
 12:        http://www.springframework.org/schema/aop
 13:        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 14:     
 15:     <!-- 引入外部的属性文件 -->
 16:   <context:property-placeholder location="classpath:jdbc.properties" />
 17:      
 18:      <!-- 配置c3p0连接池 
 19:   <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
 20:     p:driverClass="${jdbc.driverClass}"
 21:     p:jdbcUrl="${jdbc.url}"
 22:     p:user="${jdbc.username}"
 23:     p:password="${jdbc.password}" />-->
 24:   
 25:   <!-- 配置dbcp连接池 -->
 26:   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
 27:     destroy-method="close" 
 28:     p:driverClassName="${jdbc.driverClass}"
 29:     p:url="${jdbc.url}"
 30:     p:username="${jdbc.username}"
 31:     p:password="${jdbc.password}" />
 32: 
 33:   <!-- 配置Jdbc模板  -->
 34:   <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
 35:     p:dataSource-ref="dataSource" />
 36:   
 37:   <!-- 业务层 -->
 38:   <bean id="accountService" class="com.spring.demo4.AccountServiceImpl" p:accountDao-ref="accountDao"/>
 39: 
 40:   <!-- Dao类 -->
 41:   <bean id="accountDao" class="com.spring.demo4.AccountDaoImpl" p:dataSource-ref="dataSource" />
 42:   
 43:   <!-- 配置事务管理器 -->
 44:   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" 
 45:     p:dataSource-ref="dataSource" />
 46:   
 47:   <!-- 配置事务的通知:(事务的增强增强) -->
 48:   <tx:advice id="txAdvice" transaction-manager="transactionManager">
 49:     <tx:attributes>
 50:       <!-- propagation:事务的传播行为
 51:         isolation:  事务的隔离级别
 52:         read-only:只读
 53:         rollback-for:发生哪些异常回滚
 54:         no-rollback-for:发生哪些异常不回滚
 55:        -->
 56:       <tx:method name="transfer" propagation="REQUIRED"/>
 57:     </tx:attributes>
 58:   </tx:advice>
 59:   
 60:   <!-- 配置切面 -->
 61:   <aop:config>
 62:     <!-- 配置切入点 -->
 63:     <aop:pointcut expression="execution(* com.spring.demo3.AccountService+.*(..))" id="pointcut1" />
 64:     <!-- 配置切面 -->
 65:     <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1" />
 66:   </aop:config>
 67: </beans>

AccountServiceImpl.java

  1: package com.spring.demo3;
  2: import org.springframework.transaction.TransactionStatus;
  3: import org.springframework.transaction.annotation.Transactional;
  4: import org.springframework.transaction.support.TransactionCallback;
  5: import org.springframework.transaction.support.TransactionCallbackWithoutResult;
  6: import org.springframework.transaction.support.TransactionTemplate;
  7: import com.sun.istack.internal.FinalArrayList;
  8: public class AccountServiceImpl implements AccountService {
  9:   //注入转账的DAO类  
 10:   private AccountDao accountDao;
 11:   public void setAccountDao(AccountDao accountDao) {
 12:     this.accountDao = accountDao;
 13:   }  
 14:   public void transfer(String OutName, String InName, Double money) {
 15:     // TODO Auto-generated method stub
 16:      accountDao.outMoney(OutName, money);
 17: //    int i=1/0;
 18:      accountDao.inMoney(InName, money);  
 19:   }
 20: }

测试类:springtestdemo3.java

  1: package com.spring.demo3;
  2: 
  3: import javax.annotation.Resource;
  4: import org.junit.Test;
  5: import org.junit.runner.RunWith;
  6: import org.springframework.test.context.ContextConfiguration;
  7: import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  8: /**
  9:  * 声明式:基于AspectJ的XML的配置
 10:  * 
 11:  * @author su
 12:  *
 13:  */
 14: @RunWith(SpringJUnit4ClassRunner.class)
 15: @ContextConfiguration("classpath:applicationContext3.xml")
 16: public class springtestdemo3 {
 17:   //测试业务层类:
 18:   @Resource(name="accountService")
 19:   private AccountService accountService;
 20:   @Test
 21:   public void test(){
 22:     accountService.transfer("aaa", "bbb", 300d);
 23:   }
 24: }

 

2.5、声明式事务管理方式三:基于@Transactional注解

ApplicationContext4.xml

  1: <?xml version="1.0" encoding="UTF-8" ?>
  2: <beans xmlns="http://www.springframework.org/schema/beans"
  3:   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
  4:   xmlns:context="http://www.springframework.org/schema/context"
  5:   xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  6:   xsi:schemaLocation="http://www.springframework.org/schema/beans 
  7:        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  8:        http://www.springframework.org/schema/context 
  9:        http://www.springframework.org/schema/context/spring-context-3.0.xsd
 10:        http://www.springframework.org/schema/tx 
 11:        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
 12:        http://www.springframework.org/schema/aop
 13:        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 14:        
 15:     <!-- 引入外部的属性文件 -->
 16:   <context:property-placeholder location="classpath:jdbc.properties" />
 17:      
 18:     <!-- 配置c3p0连接池 
 19:   <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
 20:     p:driverClass="${jdbc.driverClass}"
 21:     p:jdbcUrl="${jdbc.url}"
 22:     p:user="${jdbc.username}"
 23:     p:password="${jdbc.password}" />-->
 24:   
 25:   <!-- 配置dbcp连接池 -->
 26:   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
 27:     destroy-method="close" 
 28:     p:driverClassName="${jdbc.driverClass}"
 29:     p:url="${jdbc.url}"
 30:     p:username="${jdbc.username}"
 31:     p:password="${jdbc.password}" />  
 32: 
 33:   <!-- 配置Jdbc模板  -->
 34:   <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
 35:     p:dataSource-ref="dataSource" />
 36:   
 37:   <!-- 业务层 -->
 38:   <bean id="accountService" class="com.spring.demo4.AccountServiceImpl" p:accountDao-ref="accountDao"/>
 39: 
 40:   <!-- Dao类 -->
 41:   <bean id="accountDao" class="com.spring.demo4.AccountDaoImpl" p:dataSource-ref="dataSource" />
 42:   
 43:   <!-- 配置事务管理器 -->
 44:   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" 
 45:     p:dataSource-ref="dataSource" />
 46:   
 47:   <!-- 开启注解事务 -->
 48:   <tx:annotation-driven transaction-manager="transactionManager"/>  
 49: </beans>

AccountServiceImpl.java

  1: package com.spring.demo4;
  2: import org.springframework.transaction.TransactionStatus;
  3: import org.springframework.transaction.annotation.Isolation;
  4: import org.springframework.transaction.annotation.Propagation;
  5: import org.springframework.transaction.annotation.Transactional;
  6: import org.springframework.transaction.support.TransactionCallback;
  7: import org.springframework.transaction.support.TransactionCallbackWithoutResult;
  8: import org.springframework.transaction.support.TransactionTemplate;
  9: import com.sun.istack.internal.FinalArrayList;
 10: /**
 11:  * @Transactional:注解中的属性
 12:  * propagation:事务的传播行为
 13:  * isolation:  事务的隔离级别
 14:  * readOnly:只读
 15:  * rollbackFor:发生哪些异常回滚
 16:  * noRollbackFor:发生哪些异常不回滚
 17:  * 
 18:  * @author su
 19:  *
 20:  */
 21: @Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,readOnly=false)
 22: public class AccountServiceImpl implements AccountService {
 23: 
 24:   //注入转账的DAO类
 25:   
 26:   private AccountDao accountDao;
 27:   public void setAccountDao(AccountDao accountDao) {
 28:     this.accountDao = accountDao;
 29:   }
 30:   
 31:   public void transfer(String OutName, String InName, Double money) {
 32:     // TODO Auto-generated method stub
 33:     accountDao.outMoney(OutName, money);
 34: //    int i=1/0;
 35:     accountDao.inMoney(InName, money);  
 36:   }
 37: }

测试类:springtestdemo4.java

  1: package com.spring.demo4;
  2: import javax.annotation.Resource;
  3: import org.junit.Test;
  4: import org.junit.runner.RunWith;
  5: import org.springframework.test.context.ContextConfiguration;
  6: import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  7: /**
  8:  * 声明式:基于注解的事务管理方式
  9:  * 
 10:  * @author su
 11:  *
 12:  */
 13: @RunWith(SpringJUnit4ClassRunner.class)
 14: @ContextConfiguration("classpath:applicationContext4.xml")
 15: public class springtestdemo4 {
 16: 
 17:   //测试业务层类:
 18:   @Resource(name="accountService")
 19:   private AccountService accountService;
 20:   @Test
 21:   public void test(){
 22:     accountService.transfer("aaa", "bbb", 300d);
 23:   }
 24: }

Spring事务