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

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

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

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

SQL

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

Q&A

解決済

1回答

3097閲覧

SQLのテーブルに共有ロックをかけたい

ypk

総合スコア83

SQL Server

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

SQL

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

0グッド

0クリップ

投稿2021/10/08 12:50

実現したいこと

プロシージャAを実行中はテーブルBにデータが入らないようにしたい

SQL

1 2 3 4CREATE PROCEDURE A 5BEGIN 6 7 insert into A_TBL 8 select 9 * 10 from 11 B_TBL 12 13END

上記のようなプロシージャAがあったとします。

テーブルBのデータを、テーブルAにInsertするプロシージャです。

Excelで呼び出す想定で作りました。

VBA

1 2BeginTrans 3 4 exec A 5 6CommitTrans 7 8

質問

・with(TABLOCKX)の使用方法
・テーブルに対して共有ロックをかける方法

を知りたいです。

上記プロシージャAを実行中にテーブルBのデータが増減してしまうと意図しないデータがテーブルAに挿入されてしまう可能性があります。
これを防ぐべく、テーブルロックを付与してあげる必要があるのかなと考えているのですがその必要はありますでしょうか?
VBA側でトランザクションを切っていれば、「ファントムリードは起こらない」で間違いないか気にしています。

そこで、テーブルAに共有ロックをかけることを検討しておりますが、共有ロックをかける方法は

SQL

1 2 3 4CREATE PROCEDURE A 5BEGIN 6 7 insert into A_TBL 8 select 9 * 10 from 11 B_TBL WITH(TABLOCKX) 12 13END

でいいのでしょうか?

しかし、

実行確認しているとロックがかかっていないように見えてしまって。。。。

下記のようなSQLを実行すると、普通にデータをInsertできてしまいます。

SQL

1 2 select 3 * 4 from 5 B_TBL WITH(TABLOCKX) 6 7 insert into B_TBL value(データ) 8 9END

with(TABLOCKX)の使い方が適切ではないからなのでしょうか?

知恵を貸していただけると嬉しいです。

どうぞよろしくお願いいたします。

補足

環境はSQL Server Management Studio 2008になります

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

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

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

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

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

maisumakun

2021/10/09 00:18

> 下記のようなSQLを実行すると WITH(TABLOCKX)とinsert intoは同じ接続から発行しているのですか?
ypk

2021/10/09 01:03

ごめんなさい、同じ接続とはどういう意味ですか、、、? 自分のイメージだと、selectする人とinsertする人は別の人のイメージです。
guest

回答1

0

ベストアンサー

上記プロシージャAを実行中にテーブルBのデータが増減してしまうと意図しないデータがテーブルAに挿入されてしまう可能性があります。

扱うテーブルが1つだけなら、意図しない事になる事はありません。

意図しない事になるのは、関係のある複数のテーブルに対して処理を行う場合に発生します。
これら一連の処理のトランザクションの競合の場合、最初に気にすべきなのはデッドロックです。

デッドロックにならないようにするには、一連の処理の順序が担保されている事が必要になります。

トランザクション内でのテーブルに関する実行順序を気にせずに行うような設計も出来ますので、もう少しトランザクションに関する理解を深める事が先決だと思います。

尚、

下記のようなSQLを実行すると、普通にデータをInsertできてしまいます。

同一のトランザクション内で連続して実行しているんだから、そうなるのは当然です。

投稿2021/10/09 02:50

編集2021/10/09 02:59
sazi

総合スコア25327

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

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

ypk

2021/10/09 03:40

ご回答ありがとうございます。 助かります。 トランザクションについて、もう少し勉強してみたいと思いました。 ひとつだけ、追加で教えてください。 >扱うテーブルが1つだけなら、意図しない事になる事はありません。 上記プロシージャAを実行中にテーブルBのデータが増減してしまうと意図しないデータがテーブルAに挿入されてしまう可能性は「ない」という理解でよろしいですか?もしそうから、その理由をもう少し詳しく知りたいです。 申し訳ございませんが、よろしくお願いいたします。
sazi

2021/10/09 06:59 編集

> 意図しないデータがテーブルAに挿入されてしまう可能性は「ない」 トランザクション分離レベル次第で、挿入されたとしても、その結果を処理側に伝播しない事は可能です。 > VBA側でトランザクションを切っていれば、「ファントムリードは起こらない」で間違いないか気にしています。 ファントムリードの有無は、トランザクション制御するかどうかではなく、先ずはトランザクション分離レベルの話です。 処理中にはテーブル操作がされないようにロックしたいという事ですが、何のためにそれをする必要があるのか分かりません。 質問では、insert into ですので、取得する際にデータが変化して対象/対象外が変化しても、取得する行為には影響ありません。 多分後続の処理に影響があるからだと思いますが、それならトランザクションの話になるので。
ypk

2021/10/09 06:04

ご丁寧にありがとうございます。 また機会があればよろしくお願いいたします。
ypk

2021/10/09 06:15

たびたび申し訳ないです、、、 WITH(TABLOCKX) をつけて共有ロックをかけ、ファントムリードを防ぐことはできないという理解でよろしいでしょうか? 申し訳ないですがよろしくお願いいたします。
sazi

2021/10/09 06:55 編集

ファントムリードされるかどうかは、どのようにロックするかだけでなく、トランザクション分離レベルにもよります。 以下参考 【SQL server】トランザクション分離レベルについて https://memorandom-nishi.hatenablog.jp/entry/2016/11/03/143533 上記だと、WITH(TABLOCKX)は悲観的ロック
sazi

2021/10/09 06:54

そもそもファントムリードがどのような時にどのように生じるかを理解しない限り、抑制する方法も正しく選択できませんので、注意して下さい。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問