发布网友 发布时间:2024-12-12 00:00
共1个回答
热心网友 时间:2024-12-12 01:50
我们开发过程中,多线程事务问题时常出现。本以为只需添加@Transactional注解,却发现事务并未生效。
原因在于,spring将数据库连接置于threadLocal中,在多线程环境下,获取的数据库连接不同,即属于不同事务。
本文基于springboot的@Async注解开启多线程,通过自定义注解和AOP实现多线程事务,避免繁琐的手动提交/回滚事务(CV即用、参数齐全、无需配置)。
一、springboot多线程(声明式)的使用方法?
1、springboot提供了注解@Async来使用线程池,具体使用方法如下:
(1) 在启动类(配置类)添加@EnableAsync来开启线程池
(2) 在需要开启子线程的方法上添加注解@Async
注意:框架默认来一个请求开启一个线程,在高并发下容易内存溢出
所以使用时需要配置自定义线程池,如下:
开启子线程方法:在需要开启线程的方法上添加注解@Async("threadPoolTaskExecutor")即可,其中注解中的参数为自定义线程池的名称。
二、自定义注解实现多线程事务控制
1.自定义注解
本文使用了两个注解共同作用实现的,主线程作为协调者,各子线程作为参与者
解释:
两个注解都是用在方法上的,须配合@Transactional(rollbackFor = Exception.class)一起使用
@MainTransaction注解用在调用方,其参数为必填,参数值为本方法中调用的方法开启的线程数,如:在这个方法中调用的方法中有2个方法用@Async注解开启了子线程,则参数为@MainTransaction(2),另外如果未使用@MainTransaction注解,则直接以无多线程事务执行(不影响方法的单线程事务)
@SonTransaction注解用在被调用方(开启线程的方法),无需传入参数
2.AOP内容
代码如下:
扩展说明:CountDownLatch是什么?
一个同步辅助类
本文中:用计数1初始化的mainDownLatch当作一个简单的开/关锁存器,或入口:在通过调用countDown()的线程打开入口前,所有调用await的线程都一直在入口处等待。
用子线程数量初始化的sonDownLatch可以使一个线程在N个线程完成某项操作之前一直等待,或者使其在某项操作完成N次之前一直等待。
3、注解使用Demo
任务方法:
调用方:
-End-