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 }

 

posted @ 2019-06-23 19:24  AliveLIP  阅读(362)  评论(0)    收藏  举报