Mysql悲観ロックと楽観ロックの使用例


悲観ロック
悲観的なロック、データは悲観的だと思います。私たちはデータを調べたらロックをかけます。他のスレッドの改竄を防止し、相手がロックを受けるまで修正できます。
例えば、次のような表があります。status=1は注文できます。status=2は注文できないという意味です。もし合併の過程で二つのユーザーが同時にstatus=1を調べたら、論理的には注文を追加してもいいですが、商品の売れ行きがオーバーします。
以下の例

CREATE TABLE `goods` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(255) DEFAULT NULL,
 `status` tinyint(4) DEFAULT NULL,
 `version` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4
INSERT INTO demo.goods (id, name, status, version) VALUES (1, 'test', 1, 1);
session 1実行

set autocommit=0;
begin;
select *
from goods where id=1 and goods.status=1 for update ;
update goods set status=2 where id=1;
session 2実行

begin;
select * from goods where id=1 for update;
この時session 2は渋滞しています。鍵はまだsession 1にあるので、鍵はずっと待っています。session 1がずっと提出しないなら、session 2は一定時間後にタイムアウトして接続を切断します。
(1205、‘ロックウオッチtimeout exceeded’;try restarting transaction)エラー、
具体的なロック待ち時間はinnodb_を設定することで可能です。ロックwaittimeoutパラメータを制御します。
このときsession 1でcomit操作を行うと、session 2は検索結果を得て、session 2にロックを渡す。
私たちはまだ通過できます。

show status like 'innodb_row_lock_%';
を選択します。
楽観ロック
楽観ロックは悲観ロックと違って、楽観ロックは自分のプログラムで実現します。
楽観的にロックして調べる時はロックしないで、更新する時だけバージョン番号を検査します。
例えば、goods表のversionが1であることを調べたら、この表を更新する時にSqlは

select * from goods where id=1;
update goods set status=2,version=version+1 where id=1 and version=1;
ここのバージョンはクエリ時のバージョン番号です。変更するたびにバージョン+1になります。バージョン番号が一致しないと更新は成功しません。
締め括りをつける
以上はこの文章の全部の内容です。本文の内容は皆さんの学習や仕事に対して一定の参考学習価値を持ってほしいです。ありがとうございます。