访问频率比较高的app接口,在后台写的异常日志会偶尔出现以下错误。

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

实所有的死锁最深层的原因就是一个:资源竞争

表现一:

一个用户A 访问表A(锁住了表A),然后又访问表B

另一个用户B 访问表B(锁住了表B),然后企图访问表A

这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B,才能继续,好了他老人家就只好老老实实在这等了

同样用户B要等用户A释放表A才能继续这就死锁了

解决方法:

这种死锁是由于你的程序的BUG产生的,除了调整你的程序的逻辑别无他法

仔细分析你程序的逻辑,

1:尽量避免同时锁定两个资源

2: 必须同时锁定两个资源时,要保证在任何时刻都应该按照相同的顺序来锁定资源.

表现二:

用户A读一条纪录,然后修改该条纪录

这是用户B修改该条纪录

这里用户A的事务里锁的性质由共享锁企图上升到独占锁(for update),而用户B里的独占锁由于A有共享锁存在所以必须等A释

放掉共享锁,而A由于B的独占锁而无法上升的独占锁也就不可能释放共享锁,于是出现了死锁。

这种死锁比较隐蔽,但其实在稍大点的项目中经常发生。

解决方法:

让用户A的事务(即先读后写类型的操作),在select 时就是用Update lock

语法如下:

select * from table1 (updlock) where ....

==========================

在联机事务处理(OLTP)的数据库应用系统中,多用户、多任务的并发性是系统最重要的技术指标之一。为了提高并发性,目前大部分RDBMS都采用加锁技术。然而由于现实环境的复杂性,使用加锁技术又不可避免地产生了死锁问题。因此如何合理有效地使用加锁技术,最小化死锁是开发联机事务处理系统的关键。

死锁产生的原因

在联机事务处理系统中,造成死机主要有两方面原因。一方面,由于多用户、多任务的并发性和事务的完整性要求,当多个事务处理对多个资源同时访问时,若双方已锁定一部分资源但也都需要对方已锁定的资源时,无法在有限的时间内完全获得所需的资源,就会处于无限的等待状态,从而造成其对资源需求的死锁。

另一方面,数据库本身加锁机制的实现方法不同,各数据库系统也会产生其特殊的死锁情况。如在Sybase 
SQL  Server 
11中,最小锁为2K一页的加锁方法,而非行级锁。如果某张表的记录数少且记录的长度较短(即记录密度高,如应用系统中的系统配置表或系统参数表就属于此类表),被访问的频率高,就容易在该页上产生死锁。

几种死锁情况及解决方法

清算应用系统中,容易发生死锁的几种情况如下:

●  不同的存储过程、触发器、动态SQL语句段按照不同的顺序同时访问多张表;

●  在交换期间添加记录频繁的表,但在该表上使用了非群集索引(non-clustered);

●  表中的记录少,且单条记录较短,被访问的频率较高;

●  整张表被访问的频率高(如代码对照表的查询等)。

以上死锁情况的对应处理方法如下:

●  在系统实现时应规定所有存储过程、触发器、动态SQL语句段中,对多张表的操作总是使用同一顺序。如:有两个存储过程proc1、proc2,都需要访问三张表zltab、z2tab和z3tab,如果proc1按照zltab、z2tab和z3tab的顺序进行访问,那么,proc2也应该按照以上顺序访问这三张表。

● 
对在交换期间添加记录频繁的表,使用群集索引(clustered),以减少多个用户添加记录到该表的最后一页上,在表尾产生热点,造成死锁。这类表多为往来账的流水表,其特点是在交换期间需要在表尾追加大量的记录,并且对已添加的记录不做或较少做删除操作。

●  对单张表中记录数不太多,且在交换期间select或updata较频繁的表可使用设置每页最大行的办法,减少数据在表中存放的密度,模拟行级锁,减少在该表上死锁情况的发生。这类表多为信息繁杂且记录条数少的表。

如:系统配置表或系统参数表。在定义该表时添加如下语句:

with  max_rows_per_page=1

● 
在存储过程、触发器、动态SQL语句段中,若对某些整张表select操作较频繁,则可能在该表上与其他访问该表的用户产生死锁。对于检查账号是否存在,但被检查的字段在检查期间不会被更新等非关键语句,可以采用在select命令中使用at 
isolation  read  uncommitted子句的方法解决。

该方法实际上降低了select语句对整张表的锁级别,提高了其他用户对该表操作的并发性。在系统高负荷运行时,该方法的效果尤为显著。

例如:    
   select * from  titles  at  isolation  read  uncommitted    
  ●  对流水号一类的顺序数生成器字段,可以先执行updata流水号字段+1,然后再执行select获取流水号的方法进行操作。

事务(进程 ID 64)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。的更多相关文章

  1. SQL Server死锁问题:事务(进程 ID x)与另一个进程被死锁在 锁 | 通信缓冲区资源上并且已被选作死锁牺牲品。请重新运行该事务。

    ### The error occurred while setting parameters### SQL: update ERP_SCjh_zzc_pl set IF_TONGBU=1 where ...

  2. 读写分离,读写分离死锁解决方案,事务发布死锁解决方案,发布订阅死锁解决方案|事务(进程 ID *)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务

    前言:         由于网站访问压力的问题,综合分析各种因素后结合实际情况,采用数据库读写分离模式来解决当前问题.实际方案中采用“事务发布”模式实现主数据库和只读数据库的同步,其中: 发布服务器1 ...

  3. Kettle 解决数据锁的问题(事务(进程 ID 51)与另一个进程被死锁在 锁 资源上)

    1.Kettle做了一个作业, 执行的时候问题发生在步骤2和步骤3之间,也就是步骤2还未完全执行完的时候,步骤3就要更新步骤2插入的数据,造成死锁.(我的理解是既然都分开作业了,那么每个作业都是一个单 ...

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

    这个是并发情况下导致的数据库事务错误,先介绍下背景. 背景 springboot+springmvc+sqlserver+mybatis 一个controller里有五六个接口,这些接口都用到了spr ...

  5. C# 最基本的涉及模式(单例模式) C#种死锁:事务(进程 ID 112)与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。请重新运行该事务,解决方案: C#关闭应用程序时如何关闭子线程 C#中 ThreadStart和ParameterizedThreadStart区别

    C# 最基本的涉及模式(单例模式) //密封,保证不能继承 public sealed class Xiaohouye    { //私有的构造函数,保证外部不能实例化        private  ...

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

    今天在做SQL并发UPDATE时遇到一个异常:(代码如下) //Parallel 类可产生并发操作(即多线程) Parallel.ForEach(topics, topic => { //DBH ...

  7. 事务 ( 进程 ID 60) 与另一个进程被死锁在锁资源上,并且已被选作死锁牺牲品

    Select * FROM [TableName] With(NoLock) .....

  8. EF 多线程TransactionScope事务异常"事务EFTransaction类定义:与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。"

    解决方案代码一:使用lock锁定 //对于锁推荐使用静态私有静态变量 private readonly static object _MyLock = new object(); /// <su ...

  9. linux查找进程id端口占用和杀死进程

    linux 查找进程id端口占用和杀死进程 ps 命令用于查看当前正在运行的进程 辅助上grep 用于搜索匹配ps -ef | grep java ps ax : 显示当前系统进程的列表 ps aux ...

随机推荐

  1. Java-Runoob-高级教程:Java 数据结构

    ylbtech-Java-Runoob-高级教程:Java 数据结构 1.返回顶部 1. Java 数据结构 Java工具包提供了强大的数据结构.在Java中的数据结构主要包括以下几种接口和类: 枚举 ...

  2. 7503E-M-irf2配置以及bfd配置

    IRF2配置 irf domain 10 irf mac-address persistent always irf auto-update enable irf auto-merge enable ...

  3. Go - 常量与运算符

    常量的定义 1. 常量的值在编译的时候就已经确定.所以,在定义的时候就必须赋值 2. 使用 const 关键字来声明常量.赋值形式与变量类似: // 标准定义 const PI int = 3.14 ...

  4. Web api help page error CS0012: Type "System.Collections.Generic.Dictionary'2错误

    1.在asp.net Boilerplate项目中,Abp.0.12.0.2,.net framework4.5.2.下载后添加了webApi的helpPage功能,调试出现错误. dubug : a ...

  5. POJ-3273 Monthly Expense (最大值最小化问题)

    /* Monthly Expense Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10757 Accepted: 4390 D ...

  6. java 字符串排序

    http://bbs.csdn.net/topics/280032929 大可不需要那样复杂了!(一)如果要排序的为字符串,如:String sortStr = "ACDFE";  ...

  7. 华为交换机S5700 vty 0 4

    最佳答案   vty 0 4 代表有5条VTY线路 由0到4 这个要看设备的版本有的设备会有更多条VTY线路比如一些企业版的设备 显示用户界面 进入TELNET 设置模式 user-interface ...

  8. 深入理解ceph-disk运行机制

    谷忠言 一,背景 目前项目所用的ceph集群内部的一个节点, 一般需要管理大约十块硬盘左右的数据存储空间,外加一到两块ssd组成的journal空间.Ceph要求每个osd对应的数据盘挂载到特定的目录 ...

  9. python以下划线开头的变量名含义

    Python核心风格:避免用下划线作为变量名的开始. 因为下划线对解释器有特殊的意义,而且是内建标识符所使用的符号,我们建议程序员避免用下划线作为变量名的开始.一般来讲,变量名_xxx被看作是“私有的 ...

  10. 比XGBOOST更快--LightGBM介绍

    xgboost的出现,让数据民工们告别了传统的机器学习算法们:RF.GBM.SVM.LASSO.........现在,微软推出了一个新的boosting框架,想要挑战xgboost的江湖地位.笔者尝试 ...