首先,各种原理、解决方案,什么使用注解、使用编程式、什么使用阿里巴巴开发的transmittable-thread-local
包 Github地址 中的TransmittableThreadLocal
等等。
百度出来一大度,这里不做阐述,主打一个眼花缭乱,可以自行百度,不过在我看来只有最合适的方法,没有一定最好的方法,这里只是提供一种可用解决方案,以及自己记录罢了,不要杠我。
在Spring管理的类,如service中
scss
@Autowired
PlatformTransactionManager transactionManager;
public void getInfoTransaction(int pageIndex) {
// 创建新的事务
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus status = transactionManager.getTransaction(def);
try {
// 处理业务
// 事务提交
transactionManager.commit(status);
} catch (Exception e) {
// 事务回滚
transactionManager.rollback(status);
}
}
可能这样你觉得这怎么用,还不是每次都要创建
但是
java
// ServiceCommon接口 空又或者有getInfoTransaction方法,看自己
public abstract class ServiceCommonImpl implements ServiceCommon{
@Autowired
PlatformTransactionManager transactionManager;
public abstract void getInfo();
public void getInfoTransaction() {
// 创建新的事务
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus status = transactionManager.getTransaction(def);
try {
// 处理业务
getInfo();
// 事务提交
transactionManager.commit(status);
} catch (Exception e) {
// 事务回滚
transactionManager.rollback(status);
}
}
}
public class Test extends ServiceCommonImpl{
@Override
public void getInfo() {
// 业务实现
}
public void test(){
// 获取线程池
ThreadPoolExecutor threadPoolExecutor = SpringUtils.getBean("BfThreadPool");
threadPoolExecutor.execute(() -> {
// 使用
getInfoTransaction();
});
}
}
你又说,这一个service我就不可能就一个方法用事务,方法改一改嘛
scala
public abstract class ServiceCommonImpl implements ServiceCommon{
@Autowired
PlatformTransactionManager transactionManager;
// 方法作为参数传入
public void getInfoTransaction(Consumer method) {
// 创建新的事务
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus status = transactionManager.getTransaction(def);
try {
// 处理业务
method.accept(null);
// 事务提交
transactionManager.commit(status);
} catch (Exception e) {
// 事务回滚
transactionManager.rollback(status);
}
}
}
public class Test extends ServiceCommonImpl {
public void test() {
ThreadPoolExecutor threadPoolExecutor = SpringUtils.getBean("BfThreadPool");
threadPoolExecutor.execute(() -> {
getInfoTransaction((nullValue) -> {
});
});
}
}
你又说,不好意思,想不到了,哈哈,G
研究其他方法吧,哈哈哈
最后,在非Spring管理类中,通过上下文获取事务管理器的bean,即transactionManager,不是PlatformTransactionManager,这个是个接口,具体实现的时候是动态加载实现类的,然后重复操作,你会发现没用,会报数据源为空的错误,有兴趣的可以试试。
至于原因,查了查,应该是Spring的事务管理器是会自动注入数据源的,你自己直接获取的是没有注入的,大概是这个意思,具体可以看以下感谢的文章。
感谢:
# Spring事务(Transaction)管理高级篇一栈式解决开发中遇到的事务问题
# 【老王读Spring Transaction-4】Spring事务管理的核心原理------PlatformTransactionManager&TransactionStatus