排他制御の罠

* おすすめ書籍:失敗しないデータベース プログラミング
Accessを使って作った売買管理のシステム。3ヶ月でほぼ完成、おおなんと速い!
さーて、あとはこの mdb をサーバーにあげて、一応レコード排他制御のテストでもやっとく?!なぁに簡単簡単、テストするだけだもん。もうできたも同然さ。
・・・こんな世迷言を吐いている上司、あなたの会社にはいませんよね?
そう、Access で、いや JET エンジンで排他制御を甘く見ていると破綻します。
…具体的に説明しろって?
Access の排他制御はすべてページ単位(1ページ=2048byte : Jet 3.52以前の場合)で行われます。
Access 2000 からはレコード単位のロックもサポートしてますので、Access の機能だけでレコードロックを実現するにはこの機能を使うのもテなんですが、どうやらこのレコード単位ロックを選択すると、やけに mdb が肥大化するという噂ですので、あんまりお勧めしません。いくらレコード単位でロックができても、破損の確率が上がったり運用に支障が出ちゃ意味ないし。
で、ページロックの場合、あるレコードをロックしようとした場合、そのレコードを含む隣接した 2048byte すべてにロックがかかります。
つまり、読んでもいないレコードなのに勝手にロックされてしまうのです。 それは(レコードセット内での見た目上)隣接した1レコードとはもちろん限りません。2048byte に何レコード入るかはその場所にあったレコードの大きさで変わります。
(ご存知かとは思いますが、SQL ベースのリレーショナル型データベースではほとんどの RDBMS でレコード長は固定でなく可変です)
これは Access というより JET エンジンの仕様ですから、当然 Visual Basic 等から mdb ファイルを扱う場合も同様です。
つまり、RDBMS にAccess(の mdb)を選んだ時点で、レコード排他制御は不可能なのです。…いや、レコード単位にこだわらないのであれば、まぁそれなりに動作します。ただし、その「それなり」が、あなたのご希望に沿うかどうかはわかりませんが。
どうしてもレコード単位でロック制御をしたい場合、データを論理的にロックするようなシステムを作るしかありません。
よく汎用機やオフコン等で行われるように、画面に表示する際にそのレコードに対し「使用中」フラグを更新してしまい、そのフラグがたっているレコードは見ないようにシステム的にロックするのです。
しかし、それでは Access の利点である「連結フォームでの更新」はできません。レコード読み込み、表示、更新のすべてをモジュール内でやらなくてはならなくなる為です。
当然、テーブルやクエリーをデータシートビューで開いた場合には論理ロックなんてできませんので、このような運用をめざす場合はここで破綻します。
それだったら、起動も早く画面がすんなり出てくる Visual Basic で作っても工数は変わらないし、論理ロックのシステムも実現できるじゃないかということになってしまいます。
まぁ、百歩譲って、ページ単位でもいいやっと妥協したとします。しかし、Access の行う排他制御動作がお気に召さない場合(たいがいの場合そうなんだよなー)、結局ワークテーブルなどを使ってプログラミングをしなければなりません。(それでも希望の動作が実現できるとは限らない)
連結フォーム、選択クエリー等を通してのデータ更新をせず、すべての更新動作をプログラムによって実現すればある程度のロック制御はできますが、それでは Access の魅力が半減してしまいます。
Access データベースは単なるファイルです。SQL Server や Oracle のように、常駐してデータベースの状態を監視するサーバープロセスが動いているわけではありません。
もし、強固なデータロックが必要な場合、Access は諦めていただいて、SQL Server や Oracle か、もしくは MSDE (現在の Express 相当) を使うしかないかと思います。(勿論、リンクテーブルとか使っていてはダメデスガ…)
MSDE は SQL Server と同等の機能(ってゆーか同じモノ)を持っていますので、SQL Server ライセンスは高いから買えないよーという場合には検討してはどうでしょう?
ただし、モノは SQL Server ですから、たとえ Access2000 の ADP ファイルを使ったとしても、Access の延長のようなキモチでは使えません。SQL Server の高度な知識が必要になることと、それ相当のプログラミング(作りこみ)が必要になることは覚悟しておいてください。
# 最近、SQL Server Compact ってのに注目してるんだけど、これも完全スタンドアロンでないと使えないね…
## クラウドに置くなら Azure SQL Database 一択だけど、運用で使おうと思うとそれなりのプランが必要になるんで、お安くはないんだよね…