并发错误:事务(进程 ID )与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品

这个是并发情况下导致的数据库事务错误,先介绍下背景。

背景

springboot+springmvc+sqlserver+mybatis

一个controller里有五六个接口,这些接口都用到了spring的事务管理,这些接口单个调用的时候都很正常,当我模拟几十个并发请求这些接口的时候,总会有一两次的mybatis的持久化操作会出错,具体错误:

nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error updating database.  Cause: java.lang.reflect.UndeclaredThrowableException
### The error may involve com.xxxxxxxxx-Inline
### The error occurred while setting parameters
### SQL: update xxxx set ccccc = ?  ,jid = ? ,status = ?                                                                                         where bcode=? and status != 0
### Cause: java.lang.reflect.UndeclaredThrowableException

根据提示的这个UndeclaredThrowableException,到网上搜索都是说mybatis的映射文件里的字段属性与model里的写的不一致。

但是如果是写法不对的话,应该每次请求的都报错啊,现在是几十次里只有一两次报错,肯定不是这个原因。

在网上搜了半天,无果,于是把代码放到服务器上再模拟并发测试一下,还是会有一两次报错,不过这次报的错就很明朗了

### Error querying database.  Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 事务(进程 ID 62)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。
### The error may exist in file [E:\kkkkk\xxxMapper.xml]
### The error may involve com.xxxxx.ppppp
### The error occurred while handling results
### SQL: SELECT b.* FROM xxxxx a RIGHT JOIN ooooo b ON a.GId = b.id  where a.bcode = ‘11111‘
### Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 事务(进程 ID 62)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。
; SQL []; 事务(进程 ID 62)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: 事务(进程 ID 62)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。

原来是并发引起的数据库事务报错,具体原因和修改看这篇:对于spring中事务@Transactional注解的理解

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

我了解了一下事务处理机制,原来这个错误是在数据库中抛出的。因为不同线程在事务中处理相同的数据时,数据库会采取让一个执行而另一个放弃执行,于是就出现上面的错了。之所以插入不容易出现这个错误,是因为插入的速度快,不容易出现。同时如果修改的时候按照条件修改数据速度就会慢,如果按照主键或索引修改速度就会快,也不容易出现这个错误。@xmt1139057136,虽然没给具体的方法确实是按照这个思路想出来的,谢谢啦。对了,我对TOMCAT在局域网内进行压力测试时,发现速度明显比本地慢的多,而且无法处理并发1000条了(本机是可以的),向请教一下。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

解决方法

1.Spring异常重试框架Spring Retry

2.把事务的隔离级别改为宽松的,read_uncommited

原文地址:https://www.cnblogs.com/shamo89/p/9073797.html

时间: 2024-10-12 03:46:09

并发错误:事务(进程 ID )与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品的相关文章

事务(进程 ID )与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务

其实所有的死锁最深层的原因就是一个:资源竞争 表现一:    一个用户A 访问表A(锁住了表A),然后又访问表B    另一个用户B 访问表B(锁住了表B),然后企图访问表A 这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B,才能继续,好了他老人家就只好老老实实在这等了    同样用户B要等用户A释放表A才能继续这就死锁了解决方法:    这种死锁是由于你的程序的BUG产生的,除了调整你的程序的逻辑别无他法    仔细分析你程序的逻辑,    1:尽量避免同时锁定两个资源    2:

linux -- 进程的查看、进程id的获取、进程的杀死

进程查看 ps ax : 显示当前系统进程的列表 ps aux : 显示当前系统进程详细列表以及进程用户 ps ax|less : 如果输出过长,可能添加管道命令 less查看具体进程, 如:ps ax|grep XXX(XXX为进程名称) 获取进程id shell获取进程ID的方法: ps -A |grep "cmdname"| awk '{print $1}' pidof "cmdname" pgrep "cmdname" 这三种在bash和

CMD查看进程ID并查杀进程

开始-运行,输入CMD打开命令行界面,输入命令netstat -ano 结束该进程C:\>taskkill /f /t /im Wiz.exe 根据进程ID杀 >taskkill /F /PID pid netstat -ano | findstr "80" (注80是你想要看查看的端口号) tasklist 看某个进程具体是哪个进程tasklist | findstr "80" (注 80是进程的id即PID)具体对应的行是协议 本地地址 外部地址 状

Linux下查找进程id并强制停止进程的脚本

Linux下的tomcat的停止脚本shutdown.sh经常失败,造成tomcat进程没关闭.所以只能手动查找进程id,然后用kill命令来强制停止.每次都要这样查一下,然后再杀进程.感觉有点麻烦,所以就把这个动作写在了脚本里面. 一.思路 这个脚本其实就2步,先获取进程id,然后 kill 掉这个进程. (1)获取进程id的方法 这个可以用 awk命令来获取 ps -ef | grep 你的进程 | grep -v grep | awk '{print $2}' 这里要把这个grep这个用

小记:事务(进程 ID 56)与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。

今天在做SQL并发UPDATE时遇到一个异常:(代码如下) //Parallel 类可产生并发操作(即多线程) Parallel.ForEach(topics, topic => { //DBHelper是一个封装的数据库操作类,下面这行代码将执行UPDATE语句 DBHelper.Update(topic, "TopicID=" + topic.TopicID); }); 出现此问题的原因是,在SQLServer默认情况下,一条SQL语句就是一个事务.而在多线程同时UPDATE

使用Shell脚本查找程序对应的进程ID,并杀死进程

#!/bin/sh NAME=$1echo $NAMEID=`ps -ef | grep "$NAME" | grep -v "$0" | grep -v "grep" | awk '{print $2}'`echo $IDecho "---------------"for id in $IDdokill -9 $idecho "killed $id"doneecho "-------------

进程序名得到进程ID和句柄与进程的公司名(使用快照和GetPeFileCompany和VerQueryValueW等函数)

WORD  GetProcessIdByName(WCHAR *processName){ DWORD processId = 0;HANDLE hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);if(hProcessSnap==INVALID_HANDLE_VALUE){return 0;} PROCESSENTRY32 pe32;pe32.dwSize = sizeof(PROCESSENTRY32); BOOL bMor

为应用程序池 ''DefaultAppPool'' 提供服务的进程意外终止。进程 ID 是 ''xxx''问题的解决方法

网上提供了很多办法,都未解决. 解决过程一波三折,依次用了下列方法: 1.解决办法 点击“开始”-“控制面板”-“管理工具”-“组件服务”-“计算机”-“我的电脑”-“DCOM”选项, 选择其下的“IIS ADMIN SERVICE”,右健选择“属性”,找到“安全”,在“启动和激活权限”中编辑“自定义”,添加帐号“Network Service”, 给该帐号赋予“本地启动”和“本地激活”的权限,重新启动IIS,(点“开始”-“运行”-“CMD”,点确定,然后运行IISRESET) 注:没有能够解

进程的基本属性:进程ID、父进程ID、进程组ID、会话和控制终端

摘要:本文主要介绍进程的基本属性,基本属性包括:进程ID.父进程ID.进程组ID.会话和控制终端. 进程基本属性 1.进程ID(PID) 函数定义: #include <sys/types.h> #include <unistd.h> pid_t getpid(void); 函数说明: 每个进程都有一个非负整型表示的唯一进程ID(PID).好比如我们的身份证一样,每个人的身份证号是唯一的.因为进程ID标示符总是唯一的,常将其用来做其他标示符的一部分以保证其唯一性,进程ID(PID)