- PR -

デッドロック対応どうしてますか?

投稿者投稿内容
こたつ
会議室デビュー日: 2008/01/15
投稿数: 11
投稿日時: 2008-01-16 21:29
JAVAで構築したWEBシステムにおいてデッドロックが発生しています。
皆さんはどのような対応をされているのでしょうか?
また、対応されていない方はどのような理由で対応していないのでしょうか?

個人的には今までの作ってきたシステムにおいては、
同じデータを複数で操作する可能性が非常に低かった為、検討した事もありませんでした。

〈簡単な説明〉
・画面では入力フォームが複数行用意されており、自由な順序で入力が可能になっている。
・画面で入力された順にDB登録を行っている。登録後は画面に登録したデータを同じ順序で再表示し、連続して更新が可能になっている。
・フレームワークの仕様上、SQLエラーが発生するとシステムエラーが発生する。
・DBはORACLE 9.0.2、AP/WEBサーバーはWebSphere

〈発生事例〉

[1]同時複数更新におけるデッドロック

ユーザAとBが同時に更新を行った場合、以下の更新順でデッドロックが発生します。


*更新順*

ユーザA:@ → A → B
ユーザB:B → A → @

@をAが更新 → BをBが更新 → AをAが更新 → AをBが更新時にAの更新待ち → BをAが更新時にBの更新待ち(Bにデッドロック発生)

[2]一括更新と複数更新の同時実行におけるデッドロック

一つのUPDATE文で複数件一括更新を行う処理と、ユーザAによる複数レコード更新を同時に行った場合、
ORACLEのUPDATE文の実行順が以下の場合にデッドロックが発生します。

*更新順*

一括更新(@ABを一つのUPDATE文で更新):@ → A → B
ユーザA :B → A → @

[1]同様に待ちが発生しデッドロック
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2008-01-16 21:59
リソースをロックする順番をルール化し統一しておけば、デッドロックは防げます。
またRDBMSにおいてデッドロック、ロックタイムアウトなどのエラーは基本的には発生するものとして、アプリケーションでハンドリングし、トランザクションの再実行を行うことが可能なように設計するのが一般的かと思われます。
こたつ
会議室デビュー日: 2008/01/15
投稿数: 11
投稿日時: 2008-01-17 00:57
ご返信ありがとうございます。
やはりそうですよね。私もその対応が一番だと思います。
しかしながら私の環境ではフレームワークの仕様上SQLExceptionが発生するとシステムエラーになってしまうので、手が打てません。
リソースのロック順も初期開発ならば手が打てるのですが、既に顧客テストになっておりまして、そう簡単には手が打てず、軽コストで可能な手段を検討している次第です。

また、フレームワークの仕様上テーブルロックを使えない為、完全に防ぐには登録順のルール化しかありません。これも初期開発ではないので・・・。

八方塞りな状況です。少し愚痴っぽくなってしましたが、皆さんのプロジェクトでの対応やご意見お聞かせください。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2008-01-17 08:20
デッドロックは一種のバグであり、フレームワークのせいにするのは如何なものかと思います。
私の場合、フレームワークでは仕様を満たせないのであれば、
その機能だけはフレームワークを使わないなどの対応を考えます。

規約やアーキテクチャより、客の要件を満たす事が大事ですよね?
こたつ
会議室デビュー日: 2008/01/15
投稿数: 11
投稿日時: 2008-01-17 09:52
仰る通り顧客の要件が第一であり、手段があればどんな方法でも対応したいと思っております。

しかしながらフレームワークが顧客とペアである為、これもまた要件です。
仮にフレームワークをはずすにした場合もDBへの登録変更削除を行う機能すべてが対象となる為、多岐にわたります。
johnes
ベテラン
会議室デビュー日: 2007/11/21
投稿数: 50
投稿日時: 2008-01-17 10:26
こんにちは。

今回キーとなりそうなフレームワークですが、あえて名前を出されていないという認識でよろしいですよね。もし名前を公開できるフレームワークでしたら公開していただいたほうが良案が出ると思います。

一般論としての対応方法が提示しづらい状況ですが。。。
引用:

こたつさんの書き込み (2008-01-17 00:57) より:
しかしながら私の環境ではフレームワークの仕様上SQLExceptionが発生するとシステムエラーになってしまうので、手が打てません。
(略)
また、フレームワークの仕様上テーブルロックを使えない為、完全に防ぐには登録順のルール化しかありません。これも初期開発ではないので・・・。


引用:

こたつさんの書き込み (2008-01-17 09:52) より:
仮にフレームワークをはずすにした場合もDBへの登録変更削除を行う機能すべてが対象となる為、多岐にわたります。


以上のことから判断すると、フレームワークの提供するメソッドにSQLを渡して、SQLの実行やそのエラーハンドリングはすべてフレームワーク側でブラックボックス的に行われてしまう。
トランザクションの管理についてもフレームワークがある程度握っているのでしょうが、さすがに1クエリーごとに完結しているわけではないですよね?
となると、そこにトランザクション管理→デッドロック対応のヒントがありそうな気がします。

※的外れな意見でしたらごめんなさい。。。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-01-17 10:48
引用:

こたつさんの書き込み (2008-01-17 00:57) より:
しかしながら私の環境ではフレームワークの仕様上SQLExceptionが発生するとシステムエラーになってしまうので、手が打てません。
リソースのロック順も初期開発ならば手が打てるのですが、既に顧客テストになっておりまして、そう簡単には手が打てず、軽コストで可能な手段を検討している次第です。


まず、どんなにリソースへのアクセス順序を統一するなどの措置をしたとしても、デッドロックは出るかもしれないという前提で、エラーハンドリングやエラー画面への遷移をちゃんとコーディングしたほうが良いと思います。デッドロックに限らず SQLException はいつかは出ますので、それに対する対応に含めることができるはずです。

引用:

こたつさんの書き込み (2008-01-17 00:57) より:
また、フレームワークの仕様上テーブルロックを使えない為、完全に防ぐには登録順のルール化しかありません。これも初期開発ではないので・・・。


登録順を決めて、その順序でダミーでレコードを UPDATE するなりしてしまえば、良いはずです。たとえば、(3)→(2)→(1) のように UPDATE したいときは、ダミーで先に(1)と(2)を UPDATE して、最終的には、(1)→(2)→(3)→(2)→(1) のように UPDATE します。
これも、もしも、UPDATE すべきレコードがなにかを特定することが、コーディングの中に入らないと制御できないとなれば、ダミーでテーブル全体を UPDATE してしまえば良いはずです。それはあまりにも実行時のコストが高いとしても、既存のコーディングをいじらないための代償としてしかたがないと思います。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2008-01-17 11:05
読み違えているかもしれませんが、

引用:

[1]同時複数更新におけるデッドロック

ユーザAとBが同時に更新を行った場合、以下の更新順でデッドロックが発生します。


*更新順*

ユーザA:@ → A → B
ユーザB:B → A → @

@をAが更新 → BをBが更新 → AをAが更新 → AをBが更新時にAの更新待ち → BをAが更新時にBの更新待ち(Bにデッドロック発生)


(1)→(2)の間にユーザーの操作が入ったりしないですよね? 単にトランザクション内の順番という話なんですよね?


引用:

・画面では入力フォームが複数行用意されており、自由な順序で入力が可能になっている。
・画面で入力された順にDB登録を行っている。登録後は画面に登録したデータを同じ順序で再表示し、連続して更新が可能になっている。


ユーザーの操作の違いによって、トランザクション内の順番が変わるとは一体どういう事でしょう??

_________________
囚人のジレンマな日々

スキルアップ/キャリアアップ(JOB@IT)