首页 > 系统相关 >死锁引起的思考:事务(进程 ID 51)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。

死锁引起的思考:事务(进程 ID 51)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。

时间:2022-11-20 21:35:29浏览次数:60  
标签:选作 记录 系统 用户 访问 死锁 进程 select

最近在做一个访问频率比较高的app接口,框架用的dapper,在我们后台写的异常日志会偶尔出现以下错误。

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

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

表现一:

    一个用户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获取流水号的方法进行操作。    

小结    

特别是在系统高负荷运行时效果尤为显著。总之,在设计、开发数据库应用系统,尤其是OLTP系统时,应该根据应用系统的具体情况,依据上述原则对系统分别优化,为开发一套高效、可靠的应用系统打下良好的基础。

标签:选作,记录,系统,用户,访问,死锁,进程,select
From: https://www.cnblogs.com/songjuntao/p/16909603.html

相关文章

  • 并发编程理论和进程理论
    目录一、并发编程理论操作系统发展史1、手工操作——穿孔卡片2、批处理——磁带存储1.联机批处理系统2.脱机批处理系统二、多道程序设计技术单道技术多道技术多道技术......
  • 并发编程 2 进程
    同步与异步#用来表达任务的提交方式同步:提交完任务之后原地等待任务的返回结果,期间不做任何事异步:提交完任务之后不愿地等待任务的返回结果,直接去做其他事,有......
  • 多进程
    进程和程序进程:正在执行的程序程序:还没有执行的代码,处于静态一、进程的状态使用进程实现多任务multiprocessing模块就是跨平台的多进程模块提供了有个Process......
  • python进程
    今日内容概要同步与异步阻塞与非阻塞创建进程的多种方式进程join方法进程间数据隔离进程间通信之IPC机制进程对象诸多方法生产者消费者模型互斥锁今日内容......
  • mongodb后台守护进程启动
    Mongodb可以通过命令行方式和配置文件的方式来启动,具体命令如下:命令行: Shell代码1.[root@localhostmongodb]#./bin/mongod--dbpath=/data/db配置文件:Shell代码1.[......
  • 配置云服务器(Ubuntu)的vnc守护进程(服务)
    tags:UbuntuServer写在前面之前配置过了基于Ubuntu的阿里云服务器,并且通过vnc远程查看UI界面,但是美中不足的一点就是每次开启ssh会话都要重新输入​​vncserver-kill......
  • linux进程回收
    1为什么要进行进程资源的回收当一个进程退出之后,进程能够回收自己的用户区的资源,但是不能回收内核空间的PCB资源,必须由它的父进程调用wait或者waitpid函数完成对子进程的回......
  • java——多线程——进程的理解
    进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程......
  • unix网络编程2.2——高并发服务器(二)多进程与多线程实现
    目录前置文章unix网络编程1.1——TCP协议详解(一):https://www.cnblogs.com/kongweisi/p/16882787.htmlunix网络编程2.1——高并发服务器(一)基础——io与文件描述符、socket编......
  • 进程间通信
    ---pipe管道概念:在内存中开辟管道空间,生产一个管道对象,多个进程使用同一个管道'''管道通信multiprocessing中管道通信只能用于有亲缘关系进程中,即父子进程,兄弟进程2.......