学習のポイント排他制御とは、複数のタスクが同一の資源を変更しようとするときに、矛盾が起こらないように、一方のタスクが完了するまで、他のタスクからのアクセスを待たせるための制御方法です。ここでは、データベースからみた排他制御を説明します。OSの管理機能からみた排他制御に関しては、「OS:排他制御」を参照してください。キーワード排他制御,同時更新,ロック機能,2相コミットメント、インテグリティ同時更新たとえば販売システムでは,売上データは各支店で発生するので,多数の人が同じ売上データベースを更新することが発生します。このように複数のジョブで同時にデータベースを更新することを同時更新といいます。その更新データのことをトランザクションといいます。あるトランザクションが更新処理をしている間に他のトランザクションが発生すると,次のような問題が発生します。在庫テーブルのある商品の在庫が200個であった。100個の入荷をAが入力し,それに続いて100個の出荷をBが入力したとする。正しい在庫は,200+100-100=200個になるはずですが,処理のタイミングにより,2や3のように誤った結果になる危険があります。Aが入荷データを入れて在庫が300になった後にBが出荷データを入力したのであれば,在庫は200個になり正しく処理される。Aの処理が完了しない内にBが入力されると,このときBは在庫が200だと認識している。そのため,Aの処理が完了して在庫が300になっても,Bの処理では200-100=100としてしまう。逆に,Aの処理が完了しない内にBの処理が完了すると,在庫はBにより100となったのが,Aにより300になってしまう。排他制御DBMSでは,このようなトラブルを回避するために排他制御の機能を持っています。上図(4)のように,一方(ここではA)が旧データをつかんだ瞬間に旧データに「ロック」をかけて,Aが処理している間にBの入力があったときは,ロックが解除するまで待たせ,Aの処理が完了したときにロックを解除して,Bの処理を開始します。このようにして,データを正しく管理することをインテグリティ(一貫性)の保持といいます。ロックには、占有ロックと共有ロックがあります。更新処理のときには占有ロックがかけられます。占有ロックがかけられている状態では、占有ロックも共有ロックもかけられません。Aが更新処理をしている間は、Bは更新処理も参照処理もできないのです。参照処理もさせないのは、Bの参照した値が、Aの更新する前の値になるか、更新後の値になるかわからないからです。参照処理のときは、共有ロックがかけられます。共有ロックがかけられているときは、共有ロックはかけれますが、占有ロックはかけられません。Aが参照処理をしているとき、Bも参照処理をすることができますが、Bが更新処理をすると、Aが参照している値がBの更新前・更新後のどちらの値になるかわからないからです。このルールにより、更新前の値になること(Aの参照が終わるまで、Bは更新できない)が保証されます。ロックの粒度ここでは,あるデータにロックをかけるとしたが,どの範囲を単位としてロックするかが問題になります。在庫テーブル全体というテーブル(ファイル)単位でロックすることもあるし,レコード単位やフィールド単位でロックすることもあります。それをロックの粒度といいます。テーブル単位のように粒度を大きくすると,誰かが更新をしていると,そのテーブル全体がロックされてしまうので,同時更新になる確率が増え,待つことになる確率が大きくなるので,全体の処理の効率が悪くなってしまいます。ロックの粒度を小さくすれば,同時更新の確率は下がりますが,ロックをかけたり解除したりする処理が複雑になるので,CPUの負荷が増大します。業務での特徴を考慮して,適切な粒度にすることが求められます。2相コミットメントAとBのを更新するトランザクションがあるとします。Aの更新は正常に処理できたのに,何らかの理由により,Bが正常に処理できなかった(異常終了した)ら,改めてAを元に戻すか,Bを正常完了するような特別な処理をしなければなりません。どちらにするのか調査したり,特別な処理をするのは大変です。これを防ぐのが2相コミットメントという方法です。Aを更新したとき,実際に更新するのではなく,更新および取消の両方ができる状態にしておきます。Bの更新を試みて,それが正常に更新できるようであれば,両方を更新し,Bが更新できないときは,Aの更新も取り消します。このようにして,AとBの両方が正しく更新されるか,両方とも更新の前の状態であるかにすることができるのです。これもインテグリティの保持に必要です。haita-seigyo)。