[初級]楽観的ロックと悲観的ロックの深い理解

[初級]楽観的ロックと悲観的ロックの深い理解

データベースロックメカニズムで説明したように、データベース管理システム(DBMS)の同時実行制御のタスクは、複数のトランザクションがデータベース内の同じデータに同時にアクセスしたときに、トランザクションの分離と統合、およびデータベースの統合が破壊されないようにすることです。

楽観的同時実行制御(楽観的ロック)と悲観的同時実行制御(悲観的ロック)は、同時実行制御に使用される主な技術的方法です。

それが悲観的なロックであろうと楽観的なロックであろうと、それは人々によって定義された概念であり、一種の考えと見なすことができます。実際、これはリレーショナルデータベースシステムの楽観的ロックと悲観的ロックの概念だけでなく、memcache、hibernate、tairなどの同様の概念でもあります。

さまざまなビジネスシナリオでは、さまざまな同時実行制御方法を選択する必要があります。したがって、楽観的同時実行制御と悲観的同時実行制御をDBMSの概念として狭義に理解しないでください。ましてや、データで提供されるロックメカニズム(行ロック、テーブルロック、排他ロック、共有ロック)と混同しないでください。実際、DBMSでは、悲観的なロックは、データベース自体が提供するロックメカニズムを使用して実現されます。

それぞれ悲観的なロックと楽観的なロックについて学びましょう。

悲観的なロック


リレーショナルデータベース管理システムでは、ペシミスティック同時実行制御(「ペシミスティックロック」、ペシミスティック同時実行制御、略して「PCC」とも呼ばれます)は同時実行制御の方法です。トランザクションが他のユーザーに影響を与える方法でデータを変更するのを防ぐことができます。トランザクションによって実行される操作が特定のデータ行に対してロックされている場合、トランザクションがロックを解放した場合にのみ、他のトランザクションはロックと競合する操作を実行できます。
悲観的な同時実行制御は、主にデータの競合が激しい環境で使用され、同時実行の競合が発生したときにロックを使用してデータを保護するコストがトランザクションのロールバックのコストよりも低い環境で使用されます。

ペシミスティックロックは、その名前が示すように、外部によって変更されるデータ(このシステム内の他の現在のトランザクション、および外部システムからのトランザクション処理を含む)に対する保守的な態度(ペシミスティック)を指します。したがって、データ処理プロセス全体では、データはロックされています。ペシミスティックロックの実現は、多くの場合、データベースによって提供されるロックメカニズムに依存します(データベース層によって提供されるロックメカニズムのみがデータアクセスの排他性を真に保証できます。そうでない場合、ロックメカニズムがこのシステムに実装されていても、外部システムが変更されないことは保証できません。データ)

データベースでは、悲観的ロックのプロセスは次のとおりです。

レコードを変更する前に、レコードに排他ロックを追加してみてください。

レコードが変更されていることを示すロックが失敗した場合、現在のクエリは待機するか、例外をスローする必要がある場合があります。具体的な対応方法は、開発者が実際のニーズに応じて決定します。

ロックが正常に保護されている場合、レコードを変更でき、トランザクションの完了後にトランザクションのロックが解除されます。

その間、レコードを変更したり、排他ロックを追加したりする他の操作がある場合は、ロックを解除するか、直接例外をスローするのを待ちます。

MySQLInnoDBでの悲観的なロック

ペシミスティックロックを使用するには、mysqlデータベースのautocommit属性をオフにする必要があります。これは、MySQLがデフォルトで自動コミットモードを使用するためです。つまり、更新操作を実行すると、MySQLはすぐに結果を送信します。autocommit = 0を設定します。

//0.开始事务
begin;/begin work;/start transaction; (三者选一就可以)
//1.查询出商品信息
select status from t_goods where id=1 for update;
//2.根据商品信息生成订单
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status为2
update t_goods set status=2;
//4.提交事务
commit;/commit work;

上記のクエリステートメントでは、select ... for updateメソッドを使用したため、排他ロックを開くことで悲観的なロックが実現されます。このとき、t_goodsテーブルでは、ID 1のデータがロックされており、他のトランザクションは、トランザクションがコミットされた後にのみ実行できます。このようにして、現在のデータが他のトランザクションによって変更されないようにすることができます。

上で述べたように、select ... for updateを使用するとデータがロックされますが、いくつかのロックレベル、MySQLInnoDBのデフォルトの行レベルロックに注意する必要があります。行レベルのロックはインデックスに基づいています。SQLステートメントでインデックスを使用しない場合、行レベルのロックは使用されず、テーブルレベルのロックはテーブル全体をロックするために使用されます。これには注意が必要です。

長所と短所

悲観的な同時実行制御は、実際には「アクセス前にロックをフェッチする」という保守的な戦略であり、データ処理のセキュリティを保証します。ただし、効率の観点から、ロックを処理するメカニズムはデータベースに追加のオーバーヘッドを引き起こし、デッドロックの可能性を高めます。さらに、読み取り専用トランザクション処理で競合が発生しないため、ロックを使用する必要はありません。システムの負荷を増やすだけで、並列処理も減らすことができます。トランザクションがデータの行をロックする場合、他のトランザクションはトランザクションが完了するのを待ってから行数を処理する必要があります。

楽観的なロック

リレーショナルデータベース管理システムでは、楽観的同時実行制御(「楽観的ロック」、Optimistic同時実行制御、略して「OCC」とも呼ばれます)は同時実行制御の方法です。複数のユーザーの同時トランザクションが処理中に相互に影響を与えることはなく、各トランザクションは、ロックすることなく、それぞれの影響を受けるデータの一部を処理できることを前提としています。データの更新をコミットする前に、各トランザクションは、トランザクションがデータを読み取った後、他のトランザクションがデータを変更したかどうかを最初にチェックします。他のトランザクションが更新された場合、コミットされているトランザクションはロールバックされます。楽観的なトランザクション制御は、HTKung教授によって最初に提案されました。

オプティミスティックロック(オプティミスティックロック)ペシミスティックロックと比較して、オプティミスティックロックの前提は、データが通常の状況では競合を引き起こさないと考えているため、データが送信および更新されると、データが競合するかどうかを正式に検出します。競合が見つかった場合、ユーザーに間違った情報を返してもらい、その方法をユーザーに決めさせます。

悲観的ロックと比較して、楽観的ロックは、データベースを処理するときにデータベースによって提供されるロックメカニズムを使用しません。楽観的なロックを実現する一般的な方法は、データバージョンを記録することです。

データバージョン、データに追加されたバージョン識別子。データを読み取るとき、バージョンIDの値が一緒に読み取られ、データが更新されるたびにバージョンIDが更新されます。更新を送信すると、データベーステーブル内の対応するレコードの現在のバージョン情報が、最初にフェッチされたバージョンIDと比較されていると判断されます。データベーステーブルの現在のバージョン番号が、最初にフェッチされたバージョンID値と等しい場合は、更新します。 、それ以外の場合は、期限切れのデータと見なされます。

データバージョンを実装する方法は2つあります。1つはバージョン番号を使用する方法、もう1つはタイムスタンプを使用する方法です。

バージョン番号を使用して楽観的なロックを実装する

バージョン番号を使用する場合、データの初期化時にバージョン番号を指定し、データが更新されるたびにバージョン番号に対して+1操作を実行できます。そして、現在のバージョン番号がデータの最新バージョン番号であるかどうかを判断します。


1.查询出商品信息
select (status,status,version) from t_goods where id=#{id}
2.根据商品信息生成订单
3.修改商品status为2
update t_goods 
set status=2,version=version+1
where id=#{id} and version=#{version};

長所と短所

楽観的な同時実行制御では、トランザクション間でデータが競合する可能性は比較的小さいと考えているため、可能な限り直接実行し、コミットするまでロックしないでください。ロックやデッドロックは発生しません。ただし、これを直接実行すると、予期しない結果が発生する可能性があります。たとえば、2つのトランザクションがデータベースの特定の行を読み取り、変更後にデータベースに書き戻します。このとき、問題が発生します。
[初級]楽観的ロックと悲観的ロックの深い理解

トランザクションによって実行された操作により、データの行にロックが適用されました。」

おすすめ

転載: blog.51cto.com/13626762/2545864