- - PR -
トランザクション中でも他の接続からはSELECTできないのでしょうか。
1
| 投稿者 | 投稿内容 |
|---|---|
|
投稿日時: 2006-06-12 13:59
Win2000Pro + Access2000+SQLSV2000を使用しております。
一つのテーブルに対してUPDATE文でデータを更新してトランザクションをかけている最中に 他のマシンから同じテーブルにSELECTをかけるとwaitがかります。 そしてコネクション時に設定したタイムアウトを過ぎるとタイムアウトのエラーになりますが、 タイムアウトだけではなくて「他でトランザクション中だったのでタイムアウトでした!」 というエラーを取得するににはどうすればよろしいでしょうか。。 何卒ご教授願います。 例) ■PC1 Cnnectionオープン トランザクションBegin SQL文実行 "UPDATE T1 ・・・" MsgBox "TESTのため待ちましょう" トランザクションCommit Cnnectionクローズ ■PC2 'PC1でMsgBoxが表示されている間に Cnnectionオープン SQL文実行 "SELECT * FROM T1 ・・・" (この時点でタイムアウトになるまでwaitがかかります。) あるいはPC2側でT1に更新はかけれないが、SELECTはできる!などはできないでしょうか。 合わせてご教授のほどよろしくお願いいたします。 |
|
投稿日時: 2006-06-12 14:13
SQL Developer Center - Columns: トランザクション分離レベルの選択とデッドロックの問題
http://www.microsoft.com/japan/msdn/sqlserver/columns/webtech/webtech3.asp |
|
投稿日時: 2006-06-12 16:25
ご返信ありがとうございました。
ご教授いただいたサイトを拝見させていただきました。 IsolationLevelかなと思い、実験してみましたが やはり他のマシンからはSELECTできませんでした。 Set objCn = New ADODB.Connection With objCn .ConnectionString = strProv .ConnectionTimeout = lngTmOut .IsolationLevel = adXactReadUncommitted .Open .BeginTranse .Execute "UPDATE T1 SET ・・・" MsgBox "テスト:ちょっと待ちましょう。" .CommitTranse End With なんとかSELECT(ダーティリードと言うのでしょうか・・)を許すことはできないでしょうか。 何卒ご教授のほどよろしくお願いいたします。 |
|
投稿日時: 2006-06-12 16:47
これですかね。
[INFO] COM+、MTS のトランザクション分離レベルの設定 http://support.microsoft.com/?scid=kb;ja;215520&spid=2852&sid=1086 |
|
投稿日時: 2006-06-13 08:21
お世話になります。うまくいきました!
が・・・気になることこが残りました。 Accessプロジェクト(.adpファイル)で作成してみましたところ SQL文を直書きしないと駄目でした。 Set objCn = Application.CurrentProject.Connection Application.CurrentProject.Connection.IsolationLevel =adXactReadUncommitted では駄目で Set objCn = Application.CurrentProject.Connection objCn.Execute "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED" だとうまくいきました。 何故 Application.CurrentProject.Connection.IsolationLevel =adXactReadUncommitted でうまくいかないのかがわかりませんが、 objCn.Execute "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED" でうまくいったのでとりあえずこれで動かしたいと思います。 さて、これでトランザクション中に別マシンからSELECTはできるようになったのですが、更新をかけようとすると希望通りwaitがかかります。 そこで首記の質問とダブりますが、 「他でトランザクション中だったのでタイムアウトでした!」 というエラーを取得するににはどうすればよろしいでしょうか。。 今のところ通常のタイムアウトとトランザクションのタイムアウトの区別がつきませんので、タイムアウトを短くして 「サーバーがこけているか、他で同じレコードを更新中のため、アクセスできませんでした」 とメッセージを出すしかございません。 何卒ご教授たまりますようよろしくお願いいたします。 |
|
投稿日時: 2006-06-13 08:43
そういう事ならロック識別用のテーブル作って
アプリ側で判定したほうがいいような気がしますが |
|
投稿日時: 2006-06-13 09:13
またはロック識別用のカラムを追加するか。
そもそもの話になりますが、未コミット状態のレコードを参照できるのは問題ないですか? |
|
投稿日時: 2006-06-13 10:20
皆様ご返信ありがとうございます。
未コミットのデータを元に在庫データを加算するなどの処理をしていないため、たまたまアプリの性質上問題は発生しませんでした。アドバイスありがとうございました。 またロック識別用のテーブル及びカラムを追加してアプリで処理する場合、ロックフラグを立てた状態でアプリが落ちた場合に、ロックされたままになりましてタイマーで消しに行くのも・・・ あ!ロックフラグの書き込み自体も本件のようにトランザクションでBeginして書きこんでCommitしなければいいんですよね! そして他からは常にフラグをダーティリードするようにすればいいんですよね! そうすれば万が一フラグを立ててアプリが落ちてもCommitしていないのでセッションが切れてフラグは元に戻るのではないでしょうか。 怪しい案かもしれませんが一度やってみます。 |
1
