当前位置:网站首页>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
边栏推荐
猜你喜欢

【深度学习】(问题记录)<对一个变量求梯度得到什么>-线性回归-小批量随机梯度下降

The use of qsort function and its analog implementation

(Text) Frameless button settings

A new generation of free open source terminal tool, so cool

梅科尔工作室-看鸿蒙设备开发实战笔记五——驱动子系统开发

(C语言)文件操作

flowable工作流所有业务概念

Re16:读论文 ILDC for CJPE: Indian Legal Documents Corpus for Court Judgment Prediction and Explanation

PyQt5快速开发与实战 8.1 窗口风格

使用 Neuron 接入 Modbus TCP 及 Modbus RTU 协议设备
随机推荐
利用R语言读取csv文件入一个数据框,然后查看各列的属性。
leetcode 剑指 Offer 47. 礼物的最大价值
【无标题】
Domino服务器SSL证书安装指南
idea2021+Activiti【最完整笔记一(基础使用)】
团队级敏捷真的没你想的那么简单
mysql安装教程【安装版】
Unity performance analysis Unity Profile performance analysis tool
echart图表清空上一次数据
The creation of a large root heap (video explanation)
Flask之路由(app.route)详解
通过构建一个顺序表——教你计算时间复杂度和空间复杂度(含递归)
学习笔记10--局部轨迹生成主要方法
ESP32 入门篇(一)使用 VS Code 进行开发环境安装
柱状图 直方图 条形图 的区别
leetcode 剑指 Offer 57. 和为s的两个数字
(文字)无框按钮设置
百度paddleocr检测训练
leetcode 剑指 Offer 52. 两个链表的第一个公共节点
Basic operations of sequence table in C language