zoukankan      html  css  js  c++  java
  • 并发错误:事务(进程 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:kkkkkxxxMapper.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

  • 相关阅读:
    Windows Server 2012 两台服务器文件同步
    Linux下非root用户运行Tomcat
    Linux离线安装mysql 5.6详细步骤
    spring再学习之整合JDBC
    spring再学习之AOP实操
    spring再学习之AOP准备
    spring再学习之注解
    spring再学习之配置详解
    spring再学习之基本概念
    spring再学习之简单测试
  • 原文地址:https://www.cnblogs.com/shamo89/p/9073797.html
Copyright © 2011-2022 走看看