zoukankan      html  css  js  c++  java
  • Spring框架10:spring编程式事务控制

    本系列笔记均是对b站教程https://www.bilibili.com/video/av47952931 的学习笔记,非本人原创

    spring编程式事务控制
    之前我们讲的都是基于配置的spring事务的实现。其实还有基于编程的方式,但是比较繁琐,实际使用的情况非常少,但是这里依然介绍一下
    首先,spring提供了一个事务控制的模板对象,我们需要在bean中将其引入:

    <!-- 配置事务模板对象-->
        <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"></bean>
    

    在TractionTemplate中:
    enter description here
    再上一个整个函数:

    @Nullable
        public <T> T execute(TransactionCallback<T> action) throws TransactionException {
            Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");
            if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
                return ((CallbackPreferringPlatformTransactionManager)this.transactionManager).execute(this, action);
            } else {
                TransactionStatus status = this.transactionManager.getTransaction(this);
    
                Object result;
                try {
                    result = action.doInTransaction(status);
                } catch (Error | RuntimeException var5) {
                    this.rollbackOnException(status, var5);
                    throw var5;
                } catch (Throwable var6) {
                    this.rollbackOnException(status, var6);
                    throw new UndeclaredThrowableException(var6, "TransactionCallback threw undeclared checked exception");
                }
    
                this.transactionManager.commit(status);
                return result;
            }
    

    而我们需要在service中先定义一个TractionTemplate对象(这里使用注解,让spring注入),然后在要控制事务的方法中调用其execute方法。这个方法需要提供一个TransactionCallBack对象,我们这里创建一个匿名内部类:

    package com.jiading.service.impl;
    
    import com.jiading.dao.impl.AccountDaoImpl;
    import com.jiading.domain.Account;
    import com.jiading.service.IAccountService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.TransactionStatus;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    import org.springframework.transaction.support.TransactionCallback;
    import org.springframework.transaction.support.TransactionTemplate;
    
    @Service("accountService")
    //在注解中进行配置
    public class AccountServiceImpl implements IAccountService {
        @Autowired
        private TransactionTemplate transactionTemplate;
        @Autowired
        AccountDaoImpl accountDao;
        @Override
        public Account findAccountById(Integer accountId) {
            Account accountById = accountDao.findAccountById(accountId);
            return accountById;
        }
        //可以对方法进行单独配置
        @Override
        public void transfer(final String sourceName, final String targetName, final Float money) {
            transactionTemplate.execute(new TransactionCallback<Object>() {
                @Override
                public Object doInTransaction(TransactionStatus transactionStatus) {
                    Account source = accountDao.findAccountByName(sourceName);
                    Account target = accountDao.findAccountByName(targetName);
                    source.setMoney(source.getMoney() - money);
                    target.setMoney(target.getMoney() + money);
                    accountDao.updateAccount(source);
                    accountDao.updateAccount(target);
                    return null;
                }
            });
        }
    }
    

    结合上图,我们就能看出,这里其实就是把我们的方法放入这个匿名内部类中执行,如果有异常会在catch中回滚,如果没有的话会在最后进行commit
    可以看出,这样的方法使用起来非常麻烦,而且对于每一个需要有事务操作的方法都要设置,不符合解耦的要求,所以不怎么用

  • 相关阅读:
    单行道
    学习C++50条忠告
    ROI
    OpenCV(图像处理)—访问像素的三种方法
    毕业课题项目——基于单目摄像头的距离测量
    API
    MFC
    STL
    debug、release
    Android中退出程序的提示框
  • 原文地址:https://www.cnblogs.com/jiading/p/12368848.html
Copyright © 2011-2022 走看看