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

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

ただいまの
回答率

90.36%

  • SQL

    2768questions

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

  • SQL Server

    668questions

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

SQLServerの排他制御に関して

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 218

kikukiku

score 323

SQLServerの排他制御に関して詳しくなく、
質問させてください。

アプリ1は処理開始時に下記1を実行します。
アプリ1は処理を終了すると、
下記2を実行します。
※下記1から3は、それぞれ1トランザクション内で実行しているものとします。

アプリ2は下記3のように更新処理を行うのですが、
table2のa='0'のときだけ更新処理を行いたいため、
下記3では、副問い合わせを用いて
条件に加えています。

問題ないでしょうか?
他テーブル間の副問い合わせであるため、
下記3の実行中に下記1が入り込む余地はあるのでしょうか?

1.アプリ1の処理開始時
update table2
set a = '1'
※1レコードのみの前提

2.アプリ1の処理終了時
update table2
set a = '0'
※1レコードのみの前提

3.アプリ2の更新処理
update table1
set col1 = 'up'
where
col2 = 'A'
and
(
select a from table2
) = '0'

マルチポスト

下記サイトに投稿しましたが、返信が付かなかったため、
こちらに投稿させて頂きました。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=90034

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2019/02/04 10:58

    > 楽観的排他制御については、この場合、どのようになるのでしょうか?

    例えば、問題のテーブルに rowversion 列を追加して、アプリ 2 の最初に SELECT クエリを投げてそれを取得しておき、UPDATE する際に再度取得して違っていたら止めるという感じです。

    楽観的同時実行制御でなく、SELECT する際に UPDLOCK をかけることで対応できれば、その方が良いかもしれません。

    キャンセル

  • kikukiku

    2019/02/04 10:59

    楽観的排他制御に関してまだ理解していないとは思いますが、
    いくつかのサイトを見てなんとなく理解したと思っています。
    現在、質問に記載させて頂いている方法が、楽観的排他制御をまさに行おうと
    いているのではないかと思いました。
    質問にある具体的な方法の場合(楽観的排他制御)、
    どのような動作になると理解すれば良いのでしょうか?

    キャンセル

  • kikukiku

    2019/02/04 11:02

    SurferOnWwwさんの書かれている内容を
    まだ理解できていないので、時間ください。

    キャンセル

回答 2

checkベストアンサー

+2

こんにちは。

SQL Server はそのトランザクションが依存するリソースをロックしてくれますので
3.の最中に、他トランザクションが1.を行うことはできません。

これは3.で副問い合わせをしていなくても同じです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/04 11:05

    3実行中に、1を実行した場合、
    table2のaは、1によってa=1になるが、
    3から見た場合、a=0と認識され、3が実行されるという理解で正しいでしょうか?
    それとも、
    そもそも、3実行中に、1は実行されないということでしょうか?

    キャンセル

  • 2019/02/04 11:39

    後者です。
    このトランザクションの実行中は「table2が行ロック」されるため、他のトランザクションは1. を実行できません。

    キャンセル

  • 2019/02/04 11:46

    全部トランザクションに束ねると、例えば「あるユーザー」が作業途中で席を離れてどこかに行ってしまったら「他のユーザー」は「あるユーザー」が返ってきて作業を終えるまで何もできなくなってしまうと思いますが、それはマズイのでは?

    キャンセル

  • 2019/02/04 11:54

    確認させてください。SurferOnWwwさんの書き込みは、
    firedflyさんの2019/02/04 11:39の書き込みは
    間違っていると言っているのでしょうか?

    キャンセル

  • 2019/02/04 12:20

    間違っていると言っているわけではありません。上に書いた状況があるとするとマズイのでは? と言ってます。UPDLOCK もその可能性があります。

    キャンセル

  • 2019/02/04 13:52

    真意理解しました。もう少し全体を考えてみます。

    キャンセル

  • 2019/02/04 15:39

    3のトランザクションの実行中は「table2が行ロック」されるため、
    1が実行されないということですが、
    この1は、3の終了まで待たされるということでしょうか?
    それとも、1は「table2が行ロック」になっているため、エラーになるのでしょうか?

    キャンセル

  • 2019/02/04 15:59

    下記の情報ソースから、上記については、エラーにならず、待たされることを理解しました。
    http://www.atmarkit.co.jp/ait/articles/0210/24/news001.html

    キャンセル

  • 2019/02/04 17:20

    場合によっては別のユーザーが事情も分からないまま長く待たされることになると思いますが、それはエラーの分類に入るような気がします。

    キャンセル

+1

そもそもになってしまいますが排他制御を実テーブルで行うのは
それなりにリスクがあると思います。

例えばアプリ1の処理開始時から終了時の間にアプリがフリーズしたり
PCの電源ごとバスンと落とせばtable2は宙ぶらりんになって
SurferOnWww氏のおっしゃる通りでアプリ2は何もできなくなると思います。

トランザクションに関係のない回答になってしまいますが
「sp_getapplock」とか「sp_releaseapplock」みたいなものが一応ありますので
そちらも調べてみられるとよろしいかと。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/04 15:22

    ご指摘頂いているリスクに関しましては、承知しています。
    あらためてご指摘頂きましてありがとうございます。
    「sp_getapplock」とか「sp_releaseapplock」に関しては
    知りませんでした。どんな技術なのか、これから調べてみます。

    キャンセル

  • 2019/02/04 15:30

    「sp_getapplock」と「sp_releaseapplock」について
    調べました。アプリケーションロックを取得したり
    解放したりすることができるものと理解しました。
    アプリ1の開始時にアプリケーションロック取得し、
    アプリ1の終了時にアプリケーションロック解放した場合、
    アプリ1がアプリケーションロック解放せずに、PCの電源ごと落ちた場合
    同じ問題が発生するのでないかと考えました。
    この理解は正しいでしょうか?

    キャンセル

  • 2019/02/04 15:50

    確かですがLockOwnerで「Session」を指定する場合はセッションが落ちたタイミングでロックが開放されたかと思います。Transactionで指定することもできたはずですが詳細は正直調べてくださいとしか言えません…。
    トランザクションに関してですが「排他ロックを取ってから実行」というふうにくめばどちらかは失敗するようにできていたと思います。

    キャンセル

  • 2019/02/04 15:54

    ご回答ありがとうございます。
    セッションが落ちたタイミングでロックを解放する機能があるんですね。
    さらに調べてみます。

    キャンセル

  • 2019/02/04 16:11

    調べてみましたが、難しすぎてすぐにわからないため、
    当方の宿題にさせてください。
    このスレッドには、記載しないこととします。

    キャンセル

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

  • ただいまの回答率 90.36%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • SQL

    2768questions

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

  • SQL Server

    668questions

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