本系列笔记均是对b站教程https://www.bilibili.com/video/av47952931 的学习笔记,非本人原创
spring编程式事务控制
之前我们讲的都是基于配置的spring事务的实现。其实还有基于编程的方式,但是比较繁琐,实际使用的情况非常少,但是这里依然介绍一下
首先,spring提供了一个事务控制的模板对象,我们需要在bean中将其引入:
<!-- 配置事务模板对象-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"></bean>
在TractionTemplate中:
再上一个整个函数:
@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
可以看出,这样的方法使用起来非常麻烦,而且对于每一个需要有事务操作的方法都要设置,不符合解耦的要求,所以不怎么用