こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

レコード単位にトランザクションかけられる?

Access2003 Win-XP です。

下記コーディングで現象は・・・
・2つのPCで同じレコードを編集すると、あとから編集する人は待機中になる。
・しかしながら、同じテーブルで最初にレコード編集中の人がいたとき、別PCの人が別レコードを編集することは可能で待機することはない(これは正常)。そして正常に更新されたかのように終了する。しかしながら、更新はされていない。
  (更新されないのにエラーハンドリングできない)

これはいったいどういうことでしょうか?
何か対策はないでしょうか?

Dim ret_value As Variant
Dim wsp As Workspace
Dim dbs As Database
Dim rsA

Set wsp = DBEngine.Workspaces(0)
Set dbs = CurrentDb
wsp.BeginTrans

Set rsA = dbs.OpenRecordset("在籍表", dbOpenDynaset, dbSeeChanges, dbPessimistic)

Do Until rsA.EOF
If rsA.[出席番号] = Me.[出席番号] Then
rsA.Edit
rsA.[氏名] = Me.[氏名]
rsA.Update
rsA.MoveLast
End If
rsA.MoveNext
Loop
rsA.Close

ret_value = MsgBox("Commit ?", vbYesNo)
If ret_value = vbYes Then
wsp.CommitTrans
Me.Requery
Else
wsp.Rollback
End If

Exit_コマンド34_Click:
Set wsp = Nothing
Exit Sub
Err_コマンド34_Click:
MsgBox Err.Description
Resume Exit_コマンド34_Click

 

投稿日時 - 2008-06-17 13:49:15

QNo.4107536

すぐに回答ほしいです

質問者が選んだベストアンサー

エラーにならず、更新も反映されないとなると、
(1)BeginTrans~CommitTransが重複しないで実行された。
(2)DBエンジンのバグ
(3)プログラム側の錯誤(エラーをスリ抜けさせてしまうなど)
のどれかなんでしょうね。当方で同様の実験しましたが、エラーになりました。
環境は以下の通りです。
OS:XP-Professional SP3
Access:11.0(Jet:4.0、ADO:2.8、VBA:6.05)

投稿日時 - 2008-06-18 14:30:40

補足

なにやら、いろいろ試しているうちに正常に動きました。
デバッグモードで止めたり、closeしなかったり、ワークスペースを開放せずに何度もテストを行ったりした影響かもしれません。

実際に他にも変な動きをした時に、一度mdbを終了させて再度実行すると正常に動く場合がよくありましたので。

今はず~っと正常に動いています。
おそらくそのへんの影響かと思われます。

nda23には、いろいろと調べていただき本当にありがとうございました。
そして、申し訳ありませんでした。

投稿日時 - 2008-06-19 09:03:19

お礼

nda23さん、本当にありがとうございました。
また分からないことがありましたら、よろしくお願いします。

投稿日時 - 2008-06-20 09:03:07

ANo.3

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

繰り返しますが、トランザクションがカブっても、Edit~Updateの時期が
重複しなければエラーになりません。これは不思議なことではありません。
私の言う更新日時の制御とは画面表示用にDBから読み出した時に取得した
レコードの更新日時と、更新のために作成したレコードセットから得られる
更新日時(最新の更新日時)を比較するこです。両者が異なるということは
「画面処理中に誰かが更新した=表示内用が古い」ということを意味します。
この場合、最新情報をDBから再取得して内容を確認するか、現行の更新を
強行するかを問い合わせるなどの処置を施します。

投稿日時 - 2008-06-17 23:54:39

補足

すみません。私の説明がへたなせいか質問の主旨が伝わっていないようです。

nda23さんの言われる更新日時の制御は別途行っておりますが、上記のコーディングでは省略しています。

問題は、レコード単位の制御が正常に行われないことです。
同じテーブルで同時に別レコードの編集を行っている人の更新が待機状態にもエラーにもならず終了したにも関わらず、実際のテーブルを見ると更新されていないことなのですが、
質問の主旨が分かっていただけたでしょうか?

何度も分かりづらい説明してしまって申し訳ありません。

投稿日時 - 2008-06-18 05:45:41

ANo.1

トランザクション管理とレコードの排他制御は別物で、目的も違います。
トランザクション管理とは一連の複数のテーブル/レコードを更新する場合、
部分的に成功、部分的に失敗ということが起き、テーブル/レコード間で、
矛盾が生じることを防ぐため、成功した更新も無かったこと(RollBack)にし、
全ての更新が成功した時、始めてその内容を反映(Commit)するという
制御です。掲題のように単一テーブルの単一レコードの更新の場合は
あまり、意味がありません。
更新の排他制御は同時更新を防ぐもので、更新を開始してから完了する
までの間、他の更新を排除するということです。掲題のオプションでは
Edit~Updateの間だけロックされますが、期間がズレていれば複数の
プロセスで同じレコードを更新してもエラーになりません。

私はこういう場合、ミューテックス代わりにファイルと、更新日時を使って
制御しています。

投稿日時 - 2008-06-17 17:06:08

補足

上記コーディングは、なるべく簡素化して現象だけを検証するために省略したものです。

更新日時による制御は元のコーディングでは行っております。

それでも上記現象が起こるのが不思議です。

投稿日時 - 2008-06-17 17:46:48

あなたにオススメの質問