ホームページ データベース mysql チュートリアル MSSQL产生死锁的根本原因及解决方法_MySQL

MSSQL产生死锁的根本原因及解决方法_MySQL

May 27, 2016 pm 01:44 PM

一、 什么是死锁

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等的进程称为死锁进程.

二、 死锁产生的四个必要条件

•互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放

•请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放

•不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放

•环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

三、 如何处理死锁

1) 锁模式

1.共享锁(S)

由读操作创建的锁,防止在读取数据的过程中,其它事务对数据进行更新;其它事务可以并发读取数据。共享锁可以加在表、页、索引键或者数据行上。在SQL SERVER默认隔离级别下数据读取完毕后就会释放共享锁,但可以通过锁提示或设置更高的事务隔离级别改变共享锁的释放时间。

2.独占锁(X)

对资源独占的锁,一个进程独占地锁定了请求的数据源,那么别的进程无法在此数据源上获得任何类型的锁。独占锁一致持有到事务结束。

3.更新锁(U)

更新锁实际上并不是一种独立的锁,而是共享锁与独占锁的混合。当SQL SERVER执行数据修改操作却首先需要搜索表以找到需要修改的资源时,会获得更新锁。

更新锁与共享锁兼容,但只有一个进程可以获取当前数据源上的更新锁,

其它进程无法获取该资源的更新锁或独占锁,更新锁的作用就好像一个序列化阀门(serialization gate),将后续申请独占锁的请求压入队列中。持有更新锁的进程能够将其转换成该资源上的独占锁。更新锁不足以用于更新数据—实际的数据修改仍需要用到独占锁。对于独占锁的序列化访问可以避免转换死锁的发生,更新锁会保留到事务结束或者当它们转换成独占锁时为止。

4. 意向锁(IX,IU,IS)

意向锁并不是独立的锁定模式,而是一种指出哪些资源已经被锁定的机制。

如果一个表页上存在独占锁,那么另一个进程就无法获得该表上的共享表锁,这种层次关系是用意向锁来实现的。进程要获得独占页锁、更新页锁或意向独占页锁,首先必须获得该表上的意向独占锁。同理,进程要获得共享行锁,必须首先获得该表的意向共享锁,以防止别的进程获得独占表锁。

5. 特殊锁模式(Sch_s,Sch_m,BU)

SQL SERVER提供3种额外的锁模式:架构稳定锁、架构修改锁、大容量更新锁。

6.转换锁(SIX,SIU,UIX)

转换锁不会由SQL SERVER 直接请求,而是从一种模式转换到另一种模式所造成的。SQL SERVER 2008支持3种类型的转换锁:SIX、SIU、UIX.其中最常见的是SIX锁,如果事务持有一个资源上的共享锁(S),然后又需要一个IX锁,此时就会出现SIX。

7.键范围锁

键范围锁是在可序列化隔离级别中锁定一定范围内数据的锁。保证在查询数据的键范围内不允许插入数据。

SQL SERVER 锁模式

缩写

锁模式

说明

S

Shared

允许其他进程读取但不能修改锁定的资源

X

Exclusive

防止别的进程读取或者修改锁定资源中的数据

U

Update

防止其它进程获取更新锁或独占锁;在搜索要修改的数据时使用

IS

Intent shared

表示该资源的一个组件被共享锁锁定了。只有在表或页级别才能获得这类锁

IU

Intent update

表示该资源的一个组件被更新锁锁定了。只有在表或页级别才能获得这类锁

IX

Intent exclusive

表示该资源的一个组件被独占锁锁定了。只有在表或页级别才能获得这类锁

SIX

Shared with intent exclusive

表示一个正持有共享锁的资源还有一个组件(一页或一行)被独占锁锁定了

SIU

Shared with intent Update

表示一个正持有共享锁的资源还有一个组件(一页或一行)被更新锁锁定了

UIX

Update with intent exclusive

表示一个正持有更新锁的资源还有一个组件(一页或一行)被独占锁锁定了

Sch-S

Schema stability

表示一个使用该表的查询正在被编译

Sch-M

Schema modification

表示表的结构正在被修改

BU

Bulk Update

在一个大容量复制操作将数据导入表中并且(手动或自动)应用了TABLOCK查

询提示时使用

2) 锁粒度

SQL SERVER 可以在表、页、行等级别锁定用户的数据资源即非系统资源(系统资源是用闩锁来保护的)。此外SQL SERVER 还可以锁定索引键和索引键范围。

通过sys.dm_tran_locks视图可以查看谁被锁定了(如行,键,页)、锁的模式以及特定资源的标志符。基于sys.dm_tran_locks视图创建如下视图用于查看锁定的资源以及锁模式(通过这个视图可以查看事务锁定的表、页、行以及加在数据资源上的锁类型)。

CREATE VIEW dblocks AS 
SELECT request_session_id AS spid, 
DB_NAME(resource_database_id) AS dbname, 
CASE WHEN resource_type='object' 
THEN OBJECT_NAME(resource_associated_entity_id) 
WHEN resource_associated_entity_id=0 THEN 'n/a' 
ELSE OBJECT_NAME(p.object_id) END AS entity_name, 
index_id, 
resource_type AS RESOURCE, 
resource_description AS DESCRIPTION, 
request_mode AS mode, 
request_status AS STATUS 
FROM sys.dm_tran_locks t LEFT JOIN sys.partitions p ON p.partition_id=t.resource_associated_entity_id 
WHERE resource_database_id=DB_ID()
ログイン後にコピー

3) 如何跟踪死锁

通过选择sql server profiler 事件中的如下选项就可以跟踪到死锁产生的相关语句。

4) 死锁案例分析

在该案例中process65db88, process1d0045948为语句1的进程,process629dc8 为语句2的进程; 语句2获取了1689766页上的更新锁,在等待1686247页上的更新锁;而语句1则获取了1686247页上的更新锁在等待1689766页上的更新锁,两个语句等待的资源形成了一个环路,造成死锁。

5) 如何解决死锁

针对如上死锁案例,分析其对应语句执行计划如下:

通过执行计划可以看出,在查找需要更新的数据时使用的是索引扫描,比较耗费性能,这样就造成锁定资源时间过长,增加了语句并发执行时产生死锁的概率。

处理方式:

1. 在表上建立一个聚集索引。

2. 对语句更新的相关字段建立包含索引。

优化后该语句执行计划如下:

优化后的执行计划使用了索引查找,将大幅提升该查询语句的性能,降低了锁定资源的时间,同时也减少了锁定资源的范围,这样就降低了锁资源循环等待事件发生的概率,对于预防死锁的发生会有一定的作用。

死锁是无法完全避免的,但如果应用程序适当处理死锁,对涉及的任何用户及系统其余部分的影响可降至最低(适当处理是指发生错误1205时,应用程序重新提交批处理,第二次尝试大多能成功。一个进程被杀死,它的事务被取消,它的锁被释放,死锁中涉及到的另一个进程就可以完成它的工作并释放锁,所以就不具备产生另一个死锁的条件了。)

四、 如何预防死锁

阻止死锁的途径就是避免满足死锁条件的情况发生,为此我们在开发的过程中需要遵循如下原则:

1.尽量避免并发的执行涉及到修改数据的语句。

2.要求每一个事务一次就将所有要使用到的数据全部加锁,否则就不允许执行。

3.预先规定一个加锁顺序,所有的事务都必须按照这个顺序对数据执行封锁。如不同的过程在事务内部对对象的更新执行顺序应尽量保证一致。

4.每个事务的执行时间不可太长,对程序段的事务可考虑将其分割为几个事务。在事务中不要求输入,应该在事务之前得到输入,然后快速执行事务。

5.使用尽可能低的隔离级别。

6.数据存储空间离散法。该方法是指采用各种手段,将逻辑上在一个表中的数据分散的若干离散的空间上去,以便改善对表的访问性能。主要通过将大表按行或者列分解为若干小表,或者按照不同的用户群两种方法实现。

7.编写应用程序,让进程持有锁的时间尽可能短,这样其它进程就不必花太长的时间等待锁被释放。

以上就是MSSQL产生死锁的根本原因及解决方法_MySQL的内容,更多相关内容请关注PHP中文网(www.php.cn)!


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPをmssqlデータベースに接続する方法 PHPをmssqlデータベースに接続する方法 Oct 23, 2023 pm 12:02 PM

PHP が mssql データベースに接続する方法には、PHP の MSSQL 拡張機能を使用する方法、PDO を使用する方法などが含まれます。詳細な導入: 1. PHP の MSSQL 拡張機能メソッドを使用して、PHP に MSSQL 拡張機能がインストールされていることを確認します。 mssql 拡張機能が PHP 構成ファイル (php.ini) で有効かどうかを確認できます。 2. PDO メソッドを使用して、PHP に PDO 拡張機能がインストールされていることを確認します。 pdo_sqlsrv 拡張機能が有効になっているかどうかは、PHP 構成ファイル (php.ini) で確認できます。

Ubuntu で PHP をインストールし、MSSQL 接続を構成するための詳細ガイド Ubuntu で PHP をインストールし、MSSQL 接続を構成するための詳細ガイド Feb 29, 2024 am 11:15 AM

Ubuntu は、サーバーの実行によく使用される人気のオープンソース オペレーティング システムです。 Ubuntu での PHP のインストールと MSSQL 接続の構成は、多くの開発者やシステム管理者が頻繁に行う必要がある操作の 1 つです。この記事では、PHP のインストール、Apache のセットアップ、MSSQLServer のインストールなどの手順を含む詳細なガイドを読者に提供し、特定のコード例を添付します。ステップ 1: PHP と関連拡張機能をインストールする まず、PHP 接続をサポートするために PHP と関連拡張機能をインストールする必要があります。

Ubuntu 環境で MSSQL データベースをサポートするために PHP をインストールする詳細な手順 Ubuntu 環境で MSSQL データベースをサポートするために PHP をインストールする詳細な手順 Feb 29, 2024 am 10:39 AM

Ubuntu 環境で MSSQL データベースをサポートするために PHP をインストールするための詳細な手順 Web アプリケーションを開発するとき、Microsoft SQL Server (MSSQL) データベースに接続する必要がある状況がよく発生します。 Ubuntu 環境で PHP を MSSQL データベースに接続するには、関連するソフトウェアをインストールし、適切な設定を構成する必要があります。次に、Ubuntu 環境で MSSQL データベースをサポートするために PHP をインストールし、特定のコードを提供する手順を詳しく紹介します。

C++ 開発におけるデッドロック問題に対処する方法 C++ 開発におけるデッドロック問題に対処する方法 Aug 22, 2023 pm 02:24 PM

C++ 開発におけるデッドロックの問題に対処する方法 デッドロックは、マルチスレッド プログラミング、特に C++ での開発でよく見られる問題の 1 つです。複数のスレッドが互いのリソースを待機すると、デッドロックの問題が発生することがあります。デッドロックが時間内に処理されないと、プログラムがフリーズするだけでなく、システムのパフォーマンスと安定性に影響を与えます。したがって、C++ 開発におけるデッドロック問題への対処方法を学ぶことは非常に重要です。 1. デッドロックの原因を理解する デッドロックの問題を解決するには、まずデッドロックの原因を理解する必要があります。デッドロックは通常、次のような場合に発生します。

golang関数の同時実行制御におけるデッドロックとスタベーションの予防と解決 golang関数の同時実行制御におけるデッドロックとスタベーションの予防と解決 Apr 24, 2024 pm 01:42 PM

Go のデッドロックと飢餓: デッドロックの防止と解決: コルーチンが相互に待機しているため、操作を実行できないことを検出するには、 runtime.SetBlockProfileRate 関数を使用します。デッドロックの防止: デッドロックを防止するには、きめ細かいロック、タイムアウト、およびロックフリーのデータ構造を使用します。飢餓: コルーチンは引き続きリソースを取得できず、飢餓を防ぐためにフェア ロックが使用されます。公平なロックの実践: 公平なロックを作成し、最初にロックを取得するためにコルーチンがロックを取得しようとするのを最長時間待機します。

Ubuntu での PHP のインストールと MSSQL データベースへの接続に関する完全なチュートリアル Ubuntu での PHP のインストールと MSSQL データベースへの接続に関する完全なチュートリアル Feb 29, 2024 am 11:18 AM

Ubuntu オペレーティング システムで PHP をインストールし、MSSQL データベースに接続することは、多くの開発者やシステム管理者が習得する必要があるスキルの 1 つです。この記事では、PHP のインストール、MSSQL サーバー ドライバーのインストール、MSSQL データベースに接続するための PHP の構成、および対応するコード例の提供など、詳細なチュートリアルを提供します。パート 1: PHP をインストールする まず、MSSQL データベースに接続できるようにするために、PHP と関連拡張機能をインストールする必要があります。ターミナルに次のコマンドを入力して、PHP と必要な拡張機能をインストールします。

Go開発のデッドロックを解決する方法 Go開発のデッドロックを解決する方法 Jun 30, 2023 pm 04:58 PM

Go 言語開発におけるデッドロック問題を解決する方法 Go 言語は、同時プログラミングで広く使用されているオープンソースの静的に型付けされたコンパイル言語です。ただし、Go 言語の同時実行モデルの特性により、開発者は同時実行プログラムを作成するときにデッドロックの問題に遭遇することがよくあります。この記事では、Go言語開発におけるデッドロック問題を解決する方法をいくつか紹介します。まず、デッドロックとは何かを理解する必要があります。デッドロックとは、複数の同時タスクが互いのリソースの解放を待っているために実行を続行できない状況を指します。 Go 言語では、デッドロックの問題は通常、リソースまたはリソースの競合が原因で発生します。

C++ マルチスレッド プログラミングにおけるデッドロックの防止および検出メカニズム C++ マルチスレッド プログラミングにおけるデッドロックの防止および検出メカニズム Jun 01, 2024 pm 08:32 PM

マルチスレッドのデッドロック防止メカニズムには次のものが含まれます。 1. ロック シーケンス。 2. テストとセットアップ。検出メカニズムには、1. タイムアウト、2. デッドロック検出器が含まれます。この記事では、共有銀行口座の例を取り上げ、ロック シーケンスによってデッドロックを回避します。転送機能は、まず送金口座のロックを要求し、次に口座への送金を要求します。

See all articles