@Transactional和synchronized同时使用时的一些问题以及解决
@Transactional和synchronized同时使用并不能保证事务一致性
背景
任何事情都有一个发生背景
有个需求【一个业务里面包含多个事务,而且还需要避免其他线程的影响,所幸的是该服务只需要启动单实例,不然还要考虑分布式的影响】
我的思路就是用@Transactional 和 synchronized来保证事务一致性和多线程影响,结果发现并没有如愿
分析原因
@Transactionalpublic ResultVo service(){synchronized (LOCK){//doservice}}
关于为什么不是用synchronized 关键字而是使用代码块锁是为了不影响其他方法,关键字默认锁的是当前类对象
一开始我的代码是这样的,乍一看好像没什么问题,但是为什么会出问题呢
排查问题
问题重现 : 一定要重现问题,任何重现不了的问题都不是问题,任何存在的问题都必能重现
由近到远 : 先确认自己的代码没问题,再考虑外部代码(如二方库,三方库)
从内到外 : 程序本质就是IPO,包含输入(input),程序(program)/指令集,输出(output),先确认输入没有问题,再确认代码逻辑
由浅入深 : 从易到难,从上到下,先上层API,http传输等,再底层API,源码,jvm等
说到这里,问题就比较容易分析了
首先我的输入没有问题
其次我逻辑代码也没有问题
接下来就是二方库和三方库了
由于事务用的是spring的事务,是基于aop实现的,ok找到问题了
由于spring的aop,会在@Transactional修饰的方法之前开启事务,之后再加锁,当锁住的代码执行完成后,在提交事务,
因此synchronized代码块执行是在事务之内执行的,可以推断在代码块执行完时,事务还未提交,其他线程进入synchronized代码块后,读取的库存数据不是最新的。
解决问题
在网上看到很多解决方案都在说在外层套一个方法,把锁的级别提高,或则说在controller加锁
这样可能会导致事务不会回滚
spring事务管理中,使用Synchronized修饰事务方法,同步为什么会失效
https://blog.csdn.net/weixin_54401017/article/details/129768305
这里提供一个解决方案,利用线程池,当然业务代码还是要加@Transactional的!!!
private ExecutorService executorService = null;//线程池public ResultVo updateOk(@RequestBody OtcTransferOutManageVo otcTransferOutManageVo){//如果线程池为null或则线程池被关闭了,创建一个单线程化线程池if (executorService == null || executorService.isShutdown()) {executorService = Executors.newSingleThreadExecutor();}if (otcTransferOutManageVo.getId() == null) {return ResultVoBuildUtils.buildResultVo( Constants.FAIL, "参数错误" );}//使用submit执行业务 Future和result.get()是为了保障线程同步,不然变成异步线程是无法捕获异常信息的Future<ResultVo> result = executorService.submit(()->{ResultVo resultVo = otcTransferOutManageService.updateOkStatus(otcTransferOutManageVo);LoggerHepler.writeInfoLog( TransferInController.class, resultVo.getMsg() );return resultVo;});executorService.shutdown();try {return result.get();} catch (Exception e) {LoggerHepler.writeErrorLog( TransferOutManageController.class, ServiceTypeENUM.ASSET_MANAGEMEN, BusinessTypeENUM.TRADE,ExceptionCodeConstants.UPDATE_MYSQL_EXCEPTION, "updateOk error!", e );return ResultVoBuildUtils.buildFaildResultVo();}}
关于这段代码有几点需要说一下
newSingleThreadExecutor()创建单线程化的线程池

通过源码可以看到 :
该方法创建一个单一工作线程的线程池,如果此线程在执行过程中失败了,会有一个新的线程来继续完成未完成的工作
任务会被保证是顺序执行的(串行),并且再任意时间都不会超过一个活跃线程
这里基于的是LinkedBlockingQueue,这是一个线程安全的阻塞队列
shutdown()方法

在调用这个方法后,会在submit的任务执行完成后将线程池变为shutdown状态,拒绝新的任务(线程池不会立刻退出,直到任务完成)
如果已经关闭了,调用此方法也不会有额外的影响
此时不能再往线程池中添加新任务,否则会抛出RejectedExecutionException异常。
Future && get()
因为这里需要获取线程执行的返回值,
无论是继承Thread类还是实现Runnable接口都无法获取到线程执行的返回值(默认是异步线程)
所以这里用到的是线程的第三种创建方式,实现callable接口重写call方法,当然重写call方法被我用lambda表达式隐含了
所以get()就是为了获取线程执行的返回值
submit()方法

传入一个Callable 任务,返回执行完成的返回值
相关文章:
@Transactional和synchronized同时使用时的一些问题以及解决
Transactional和synchronized同时使用并不能保证事务一致性背景任何事情都有一个发生背景有个需求【一个业务里面包含多个事务,而且还需要避免其他线程的影响,所幸的是该服务只需要启动单实例,不然还要考虑分布式的影响】我的思路就是用Transactional 和 synchronized来保证事务…...
贪心-根据身高重建队列
假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。 请你重新构造并返回输入数组 peopl…...
「解析」牛客网-华为机考企业真题 21-40
又是一年春招时,有幸收到华为自动驾驶算法岗,之前刷题不多,在此汇总下牛客网的真题,主要采用Python编写,个人觉得语言只是实现工具而已,并不是很关键,Python简洁易懂,更加适合算法工…...
JAVA练习92-快乐数
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 提示:这里可以添加本文要记录的大概内容: 3月28日练习内容 提示:以下是本篇文章正文内容,下面案例可供参考 一、题目-…...
BPF 之路:技术背景
目录 引言 什么是BPF 历史 组成 执行机制 BPF 和ebpf 的关系 BCC、bpftrace、IO Visor BCC 项目的quick start execsnoop biolatency 动态插桩:kprobes和uprobes 概念 缺点 静态插桩:tracepoint 和USDT 概念 缺点 推荐的方案 初识bpft…...
C++—— set、map、multiset、multimap
目录 关联式容器 概念 键值对 树形关联式容器 set 介绍 定义方式 使用 map 介绍 使用 multiset 介绍 使用 multimap 介绍 使用 相关的OJ题 前K个高频单词 关联式容器 概念 我们之前接触过的一些容器,比如:vector、list、deque、forwa…...
Qlib使用
Qlib https://github.com/microsoft/qlib 将csv文件转化为Qlib的数据格式:https://qlib.readthedocs.io/en/latest/component/data.html#converting-csv-format-into-qlib-format 注意每支股票都要保存成单独一个文档,且文档名字与股票代号一致。 其中f…...
TL-WDR7660 httpProcDataSrv任意代码执行漏洞复现分析
01 漏洞简述 2023年1月31日,CNVD公开了一个由国内安全研究员提交的TL-WDR7660 httpProcDataSrv任意代码执行漏洞,编号为CNVD-2023-05404,同时公开了漏洞利用详情,poc代码链接为https://github.com/fishykz/TP-POC。从poc代码详情…...
基于DDS的SOA测试方案实现
随着以太网技术在车载网络中的应用,各种基于以太网的中间件也相继被应用在车内,如果对车载网络有过相关了解的小伙伴,对于作为中间件之一的DDS(数据分发服务Data Distribution Service)可能并不陌生;若没有…...
LibTorch中Windows系统环境配置及CUDA不可用问题解决
前言:本文对在Windows系统上进行LibTorch开发环境配置及相关问题解决做一个较为详细的记录,以便后续查询使用。 使用环境版本: Windows 11 Visual Studio 2022 CUDA 12.0 LibTorch 1.13.1_cu11.7 目录一、LibTorch简介二、LibTorch下载安装三…...
Java并发编程实战二
线程间的通讯方式 1.volitate(缓存一致性协议),synchronize,lock(都保证可见性) 2.wait.notify,await(),signal(前两个是Object,后两个属于lock) 3.管道输入、输出流 (示例代码:PipeInOut.java)(目前几乎没人使用) 管道输入/输…...
Linux中最基本的命令ls的用法有哪些?
Linux是一种流行的操作系统,被广泛应用于服务器和个人电脑。Linux命令行界面是使用Linux操作系统的关键。其中一个最基本的命令是"ls"命令,该命令用于列出指定目录中的所有文件和子目录。在这篇文章中,我们将探讨ls命令及其各种用途…...
第 100002(十万零二)个素数是多少?
题目描述 素数就是不能再进行等分的整数。比如7,11。而 9 不是素数,因为它可以平分为 3 等份。一般认为最小的素数是2,接着是 3,5,... 请问,第 100002(十万零二)个素数是多少? 请注意࿱…...
Lua迭代器
Lua迭代器 迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。 在 Lua 中迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素。 泛型 f…...
同步与互斥之信号量
目录 1、信号量用于线程的互斥 验证 2、信号量用于线程的同步 验证 3、无名信号量用于进程间互斥 代码一 代码二 验证 4、有名信号量 用于进程间同步和互斥 验证 信号量广泛用于进程或线程间的同步和互斥,信号量本质上是一个非负的整数计数器,它…...
如何当个优秀的文档工程师?从 TC China 看技术文档工程师的自我修养
本文系 NebulaGraph Community Academic 技术文档工程师 Abby 的参会观感,讲述了她在中国技术传播大会分享的收获以及感悟。 据说,技术内容领域、传播领域的专家和决策者们会在中国技术传播大会「tcworld China 2022」大会上分享心得。作为一名技术文档工…...
如何学习k8s
学习Kubernetes可以遵循以下步骤: 了解Kubernetes的基本概念和架构。学习Kubernetes前,需要了解它的基本概念和组成部分,包括Pod、Service、ReplicaSet、Deployment、Namespace等等,同时也需要了解Kubernetes的整体架构和工作原理…...
【SSM】MyBatis(十.动态sql)
文章目录1.if2.where3.trim4.set5. choose when otherwise6.foreach6.1 批量删除6.2 批量增加7.sql1.if <select id"selectByMultiCondition" resultType"Car">select * from t_car where 1 1<if test"brand ! null and brand ! ">…...
最近很多人都在说 “前端已死”,讲讲我的看法
转自 : 掘金 作者 : Ethan_Zhou 现状 我记得去年脉脉的论调还都是 客户端已死,前后端还都是一片祥和,有秀工资的,有咨询客户端转前端的,怎么最近打开脉脉一看,风向变了? 随便刷几下,出来的信息…...
大家好,我是火旺技术
大家好,我是火旺技术 在Internet高速发展的今天,我们生活的各个领域都涉及到计算机的应用。这其中,家乡特色推荐的网络应用已经成为外国家乡推荐系统的一种很普遍的方式。不过,在国内,管理网站可能还处于起步阶段。 …...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
