数据库死锁处理方法

数据库死锁处理方法,第1张

mysql数据死锁解决方法如下:

1、对于按钮等控件,点击后使其立刻失效,不让用户重复点击,避免对同时对同一条记录 *** 作。

2、使用乐观锁进行控制。乐观锁大多是基于数据版本(Version)记录机制实现。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是 通过为数据库表增加一个“version”字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数 据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。乐观锁机制避免了长事务中的数据 库加锁开销(用户A和用户B *** 作过程中,都没有对数据库数据加锁),大大提升了大并发量下的系统整体性能表现。Hibernate 在其数据访问引擎中内置了乐观锁实现。需要注意的是,由于乐观锁机制是在系统中实现,来自外部系统的用户更新 *** 作不受系统的控制,因此可能会造 成脏数据被更新到数据库中。

锁是需要事务结束后才释放的。

一个是 MVCC,一个是两阶段锁协议。

为什么要并发控制呢?是因为多个用户同时 *** 作 MySQL 的时候,为了提高并发性能并且要求如同多个用户的请求过来之后如同串行执行的一样(为了解决脏读、不可重复读、幻读)

官方定义:

两阶段锁协议是指所有事务必须分两个阶段对数据加锁和解锁,在对任何数据进行读、写 *** 作之前,事务首先要获得对该数据的封锁;在释放一个封锁之后,事务不再申请和获得任何其他封锁。

对应到 MySQL 上分为两个阶段:

但是两阶段锁协议不要求事务必须一次将所有需要使用的数据加锁(innodb在需要的索引列数据才锁行),并且在加锁阶段没有顺序要求,所以这种并发控制方式会形成死锁。

MySQL有两种死锁处理方式:

死锁检测 (默认开启)

死锁检测的原理是构建一个以事务为顶点、锁为边的有向图,判断有向图是否存在环,存在即有死锁。

回滚

检测到死锁之后,选择插入更新或者删除的行数最少的事务回滚,基于 INFORMATION_SCHEMA.INNODB_TRX 表中的 trx_weight 字段来判断。

收集死锁信息:

减少死锁:

死锁解决:

死锁,简而言之,两个或者多个trans,同时请求对方正在请求的某个对象,导致双方互相等待。简单的例子如下:\x0d\x0a trans1trans2\x0d\x0a ------------------------------------------------------------------------\x0d\x0a 1.IDBConnection.BeginTransaction 1.IDBConnection.BeginTransaction\x0d\x0a 2.update table A2.update table B\x0d\x0a 3.update table B3.update table A\x0d\x0a 4.IDBConnection.Commit4.IDBConnection.Commit \x0d\x0a 那么,很容易看到,如果trans1和trans2,分别到达了step3,那么trans1会请求对于B的X锁,trans2会请求对于A的X锁,而二者的锁在step2上已经被对方分别持有了。由于得不到锁,后面的Commit无法执行,这样双方开始死锁。\x0d\x0a 好,我们看一个简单的例子,来解释一下,应该如何解决死锁问题。\x0d\x0a -- Batch #1\x0d\x0a CREATE DATABASE deadlocktest\x0d\x0a GO\x0d\x0a USE deadlocktest\x0d\x0a SET NOCOUNT ON\x0d\x0a DBCC TRACEON (1222, -1)\x0d\x0a -- 在SQL2005中,增加了一个新的dbcc参数,就是1222,原来在2000下,我们知道,可以执行dbcc\x0d\x0a --traceon(1204,3605,-1)看到所有的死锁信息。SqlServer 2005中,对于1204进行了增强,这就是1222。\x0d\x0a GO \x0d\x0a \x0d\x0a IF OBJECT_ID ('t1') IS NOT NULL DROP TABLE t1\x0d\x0a IF OBJECT_ID ('p1') IS NOT NULL DROP PROC p1\x0d\x0a IF OBJECT_ID ('p2') IS NOT NULL DROP PROC p2\x0d\x0a GO\x0d\x0a CREATE TABLE t1 (c1 int, c2 int, c3 int, c4 char(5000)) \x0d\x0a GO\x0d\x0a DECLARE @x int\x0d\x0a SET @x = 1\x0d\x0a WHILE (@x = [@p1] AND [t1].[c2] = [@p1] AND [deadlocktest].[dbo].[t1].[c2] 回答于 2022-11-16


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/9991868.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-04
下一篇2023-05-04

发表评论

登录后才能评论

评论列表(0条)

    保存