Access VBAの深淵へ:排他制御を制する者がマルチユーザー環境を制す
こんにちは。Accessの現場で戦い続ける皆さん、今日もお疲れ様です。
Access VBAを使っていて、「複数の人が同時に同じデータを触ったらどうなるんだろう?」と考えたことはありませんか? 開発当初は一人でテストしているから問題なくても、いざ現場にリリースすると「書き込みエラーが発生しました」「他のユーザーが使用中です」といったトラブルが頻発する……。これは、「排他制御」の概念を理解することで解決できる、避けては通れないステップです。
今日は、DAO.Recordsetの `LockEdits` プロパティを軸に、悲観的排他制御と楽観的排他制御という「二つの守り方」をマスターしましょう。ここをクリアすれば、あなたのAccessシステムは一気にプロの現場で通用する品質に変わります。
—
1. なぜ「ロック」が必要なのか?
想像してみてください。AさんとBさんが同時に一つのレコードを編集し、更新ボタンを押そうとしています。
もし何も制御していなければ、Aさんの変更の上にBさんの変更が上書きされ、Aさんの努力は水の泡になります。これを防ぐのが「排他制御」です。
Access VBAの `DAO.Recordset` には、この衝突を防ぐための強力な武器 `LockEdits` が備わっています。
—
2. 悲観的排他制御(Pessimistic Locking)
「編集し始めたら、誰にも触らせない」
`LockEdits = True` を指定する方法です。
レコードを `Edit` メソッドで編集可能にした瞬間、他のユーザーはそのレコードをロックされ、編集できなくなります。
- メリット: データの整合性が極めて高い。
- デメリット: ロックが長時間続くと、他のユーザーがシステムを使えなくなる(デッドロックや待ち時間)。
【コード例】
Sub UpdateRecord_Pessimistic()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
‘ 編集対象のクエリを開く
Set rs = db.OpenRecordset(“T_売上管理”, dbOpenDynaset)
‘ 【ここが重要!】悲観的排他制御を有効化
rs.LockEdits = True
rs.FindFirst “ID = 101”
If Not rs.NoMatch Then
rs.Edit ‘ この瞬間、他ユーザーはこのレコードを編集不可にする
rs!売上金額 = 5000
rs.Update ‘ Updateした時点でロックが解除される
End If
rs.Close
Set rs = Nothing
End Sub
—
3. 楽観的排他制御(Optimistic Locking)
「誰も触っていないと信じる。でも、もし触っていたら…」
`LockEdits = False` を指定する方法です。
編集開始時にはロックをかけません。`Update` を実行するその瞬間に、レコードが他人に変更されていないかをチェックします。
- メリット: システム全体の動作が軽快。多人数の同時接続に強い。
- デメリット: 衝突した際に「エラー」が発生するため、その後のリカバリー処理(再読み込みやユーザーへの通知)が必要。
【コード例】
Sub UpdateRecord_Optimistic()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset(“T_売上管理”, dbOpenDynaset)
‘ 【ここが重要!】楽観的排他制御(デフォルトはFalse)
rs.LockEdits = False
rs.FindFirst “ID = 101”
If Not rs.NoMatch Then
On Error GoTo ErrorHandler
rs.Edit
rs!売上金額 = 5000
rs.Update ‘ ここでデータが他者に変更されていればエラーになる
End If
rs.Close
Exit Sub
ErrorHandler:
If Err.Number = 3197 Then ‘ データが変更されたというエラーコード
MsgBox “誰かがデータを変更しました。再読み込みしてください。”
Else
MsgBox “エラー発生: ” & Err.Description
End If
End Sub
—
4. どっちを使えばいいの?判断基準
現場での使い分けの極意は、「データの重要度」と「競合の可能性」のバランスです。
- 悲観的(LockEdits = True)を選ぶべきケース:
- 在庫数や残高など、絶対に数字をずらしてはいけないクリティカルなデータ。
- 編集時間が短く、すぐに更新が完了する場合。
- 楽観的(LockEdits = False)を選ぶべきケース:
- マスターデータなど、同時編集の可能性が低いデータ。
- Web経由でのAccess利用など、ネットワークが不安定でロックの解放が遅れるリスクがある環境。
—
最後に:先輩からのアドバイス
初学者のうちは、「エラーが出ないこと」を優先して楽観的制御を選びがちです。しかし、真のエンジニアは「もし衝突したらどう振る舞うべきか?」というエラーハンドリングまで設計することで、システムの信頼性を担保します。
まずは既存のシステムで `LockEdits` がどうなっているか確認してみてください。
「なんとなく動いている」状態から「仕組みを制御している」状態へ。ここをクリアすれば、あなたのVBAスキルは一段上の領域へ到達したと言っても過言ではありません。
また分からないことがあれば、いつでも聞きに来てくださいね。あなたの開発ライフがより良いものになるよう、応援しています!
