当前位置:网站首页>Multi-threading scheme to ensure that a single thread opens a transaction and takes effect
Multi-threading scheme to ensure that a single thread opens a transaction and takes effect
2022-07-30 10:09:00 【silly fish love programming】
When we develop, we often encounter the problem of multi-threaded transactions.I thought it was enough to add the @Transactional annotation. In fact, after you added the annotation, you will find that the transaction is invalid.Reason: The database connection spring is placed in threadLocal. In multi-threaded scenarios, the database connections obtained are different, that is, they belong to different transactions.
Spring supports programmatic transactions and declarative transactions. The most primitive transaction management method provided by Spring is based on TransactionDefinition, PlatformTransactionManager, and TransactionStatus programmatic transactions.
The transaction management of TransactionTemplate is the encapsulation of the original transaction management method using the template method design pattern, so we can also use TransactionTemplate to manage transactions.
Today, let's talk about the solution for a single thread to start a transaction:
1. Propose the thread method directly and add the @Transactional annotation
// Method to enable multithreadingpublic void testTransactional() throws ExecutionException, InterruptedException {int inter = 3;ExecutorService executorService = Executors.newFixedThreadPool(inter);ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) executorService;FutureTask[] integerFuture = new FutureTask[inter];for (int i = 0; i < inter; i++) {int finalI = i + 1;integerFuture[i] = new FutureTask<>(() -> {testTransactionalServiceZi.testTransactionalZi(finalI, "calculation" + finalI);System.out.println("Multiple threads are running---" + finalI);return "Business execution succeeded";});poolExecutor.execute(integerFuture[i]);}for (int i = 0; i < inter; i++) {System.out.println("integerFuture return result = " + i + "==" + integerFuture[i].get());}}// single thread call, add [email protected] void testTransactionalZi(int num, String str) {// modify data ===1===AdCourse adCourse = new AdCourse();adCourse.setId(num);adCourse.setName(str);int i = adCourseMapper.updateById(adCourse);// modify data ===2===adCourse.setId(num + 3);adCourse.setName(str + 0);int result = adCourseMapper.updateById(adCourse);// Manually create an exception (the transaction will take effect)result = 1/0;}
2. Use TransactionTemplate to manage transactions
By interpreting the source code, TransactionTemplate encapsulates PlatformTransactionManager.It is more troublesome for us to write PlatformTransactionManager by ourselves to manage transactions, so we use TransactionTemplate to display the code, as follows:
@Servicepublic class TestTransactionalServiceImpl implements TestTransactionalService {@Autowiredprivate TestTransactionalServiceZi testTransactionalServiceZi;// Use Template to control [email protected] TransactionTemplate template;public void testTransactional() throws ExecutionException, InterruptedException {int inter = 3;ExecutorService executorService = Executors.newFixedThreadPool(inter);ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) executorService;FutureTask[] integerFuture = new FutureTask[inter];for (int i = 0; i < inter; i++) {int finalI = i + 1;integerFuture[i] = new FutureTask<>(() -> {return template.execute(new TransactionCallback() {@Overridepublic String doInTransaction(TransactionStatus transactionStatus) {testTransactionalServiceZi.testTransactionalZi(finalI, "Calculate 666" + finalI);System.out.println("Multiple threads are running---" + finalI);return "Business execution succeeded";}});});poolExecutor.execute(integerFuture[i]);}for (int i = 0; i < inter; i++) {System.out.println("integerFuture return result = " + i + "==" + integerFuture[i].get());}}}// method to callpublic void testTransactionalZi(int num, String str) {// modify data ===1===AdCourse adCourse = new AdCourse();adCourse.setId(num);adCourse.setName(str);int i = adCourseMapper.updateById(adCourse);// modify data ===2===adCourse.setId(num + 3);adCourse.setName(str + 0);int result = adCourseMapper.updateById(adCourse);// Manually create an exception (the transaction will take effect)result = 1/(num-1);}
Print result: The first thread did not execute successfully, an exception occurred, and the data did not change.
Summary: The above two methods can guarantee the problem of single thread transaction in multithreading
边栏推荐
猜你喜欢
随机推荐
HCIP - MPLS VPN experiment
Baidu promotion assistant encounters duplicate keywords, verification errors, how to delete redundant ones with one click
判断一颗树是否为完全二叉树——视频讲解!!!
(C语言)文件操作
An article to understand service governance in distributed development
EViews 12.0 software installation package download and installation tutorial
快解析结合用友时空
ESP32 入门篇(一)使用 VS Code 进行开发环境安装
How to avoid CMDB becoming a data island?
debian10 install djando
20220728 Use the bluetooth on the computer and the bluetooth module HC-05 of Huicheng Technology to pair the bluetooth serial port transmission
PyQt5快速开发与实战 7.4 事件处理机制入门 and 7.5 窗口数据传递
仿牛客网项目第二章:开发社区登录模块(详细步骤和思路)
Version management of public Jar packages
Always remember: one day you will emerge from the chrysalis
【HMS core】【FAQ】HMS Toolkit典型问题合集1
105. 从前序与中序遍历序列构造二叉树(视频讲解!!)
快解析结合任我行crm
北京突然宣布,元宇宙重大消息
一文理解分布式开发中的服务治理