質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Transact-SQL

Transact-SQLはSybase ASEとMIcrosoft SQLサーバで対応されているSQLの機能拡張版です。

Q&A

2回答

8258閲覧

デッドロックの原因と対策

ya_ay

総合スコア13

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Transact-SQL

Transact-SQLはSybase ASEとMIcrosoft SQLサーバで対応されているSQLの機能拡張版です。

0グッド

0クリップ

投稿2019/08/06 05:29

編集2019/10/10 06:57

トランザクションのデッドロックについて

Aテーブル
Bテーブルの2つのテーブルがあり
AテーブルにINSTEAD OF INSERTトリガががあります。

トリガの動作としては
AテーブルにINSERTされたとき、
INSERTせずに、特定カラムのデータが同一のものがないか確認し
あったらAテーブルの該当レコード削除してからINSERTします。
なかった場合そのままINSERTします。
(トリガの動作はもっとよいやり方があるのかもしれませんが)

補足としては
・Aテーブルには一つのレコードしかINSERTされません。同時に複数レコードはないです。
・ほかにAテーブルにアクセスする動作はありません。
・Aテーブルには次々にINSERTがきます。

問題のデッドロックなのですが、AテーブルにINSERTするときに発生します。
デッドロックが発生する概念は理解したつもりですが、
今回はトリガ内の処理中にAテーブルへのINSERTが原因なのでしょうか。
トリガーの処理に入った時点でAテーブルはロックされない状態となってしまうのでしょうか。

対策等あれがご教示ください。
よろしくお願いします。


追記
トリガの内容を追記します。
それと、bテーブルについて記載がありませんでした。
Bはトリガ内で使用しています。

INSTED OF INSERT AS BEGIN TRAN SELECT *FROM Aテーブル WITH (TABLOCK) SET NOCOUNT ON; INSERT INTO Bテーブル SELECT *FROM INSERTED --AテーブルにA列が一致するレコードがあるか IF (NOT EXISTS (SELECT Aテーブル.A列 FROM Aテーブル,INSERTED WHERE Aテーブル.A列= INSERTED.A列 )) --A列が一致するレコードがない。 INSERT INTO Aテーブル SELECT *FROM INSERTED ELSE --AテーブルにA列が一致するレコードがある BIGIN DECLARE @R int SET @R = (SELECT A列 FROM INSERTED) DELETE FROM A列 WHERE A列 =@R INSERT INTO Aテーブル SELECT *FROM INSERTED END COMMIT TRAN

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2019/08/06 07:38

トランザクション分離レベルについても質問に追記した方が良いですね。
mather

2019/08/06 07:58

Bテーブルは質問には関係ないのですね…?
mather

2019/08/06 08:06

実際のトリガーのスクリプトを提示したほうが解決しやすいと思います。
mather

2019/08/06 08:09

特に WITH (nolock) などついているかどうかで挙動が変わるので。
KOZ6.0

2019/08/07 00:12

SQL Server にはあまり明るくないですが、A 列がプライマリキーでないと DELETE で複数レコードにロックがかかるのでは? あと、INSERTED テーブルって複数件入ることを想定しなくてよいんでしょうか?
guest

回答2

0

トリガーで行われる内容は、その契機となった処理のトランザクションに含まれます。
トランザクション全体で不備が無いか確認して下さい。

投稿2019/08/06 05:44

sazi

総合スコア25173

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

SQL Server の INSTEAD トリガーは、トリガーを呼び出す契機となった処理と同じトランザクションになります。
なので、呼び出し側でロックしてなければ、トリガー突入時でもロックされていません。

ただし書かれたとおりだとすると、トリガ内でSELECTを実施しているので、ここでロックかけてませんか?
そして、ここでロックがかかったとすると、トリガが終了するまでに「トリガ内でかけたロックは解消する」必要があります。

投稿2019/08/06 05:39

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ya_ay

2019/08/06 06:45

>トリガーを呼び出す契機となった処理と同じトランザクションになります。なので、呼び出し側でロックしてなければ ’トリガを呼び出す契機’とはAテーブルへのINSERTということでしょうか。 "INSERT INTO Aテーブル・・・・・という INSERT文しかありません。 初歩的なことで申し訳ないですがINSERT文ではロックされないということでしょうか。 >トリガ内でSELECTを実施しているので、ここでロックかけてませんか? 現在試行錯誤中で トリガ内の最初にBEGIN TRAN 最後にCOMMIT TRANを追加しましたがデッドロックが発生してしまいます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問