Mysqlシリーズ進歩一:MySQL楽観ロックと悲観ロックを実現

3120 ワード

[OTC](Mysqlシリーズ進歩一:MySQL楽観ロックと悲観ロックを実現)
前言
データベースベースの楽観的なロックと悲観的なロックの主な目的は、データベースの同時実行時にデータの更新が一致しないことによる問題を解決することである.
悲観ロック
悲観ロックには独占と排他の2つの特性があり、データを修正するときはまずロックを手に入れなければならない.そうしないと、直接拒否する.操作データの過程で、全称はロックを持ち、操作が終わった後、ロックを解除する.
悲観的ロックを実現
一般的にMySQLで悲観的なロックを実現し、select...for updateを使用して実現し、あるリソースに対して1つのトランザクションが文を呼び出すと、他のすべてのリソースを呼び出すトランザクションは最初のトランザクションが解放されるまで待つしかない.
# 1.      
CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
insert into test (name,age) values('zhao',20);
insert into test (name,age) values('xi',21);

# 2.           
set autocommit = 0;

# 3.   1   
select * from test where id = 1 for update; 

# 4.   2   
update test set age = 22 where id = 1;
commit;

##       2       update   

# 5.    1    commit;

##       2    1     ,   2     .

for update悲観ロックの問題
for updateのフィールドがインデックスまたはプライマリ・キーの場合、インデックスまたはプライマリ・キーに対応するローのみがロックされます.そうしないと、テーブル全体がロックされ、使用時に注意してください.

# 1.   1   
select * from test where name = 'zhao' for update;

# 2.   2   
select * from test where name = 'xi' for update;

##       2      

# 3.   1    rollback

##     2    1      ,   2     

# 4.  age      
create index idx_test_age on test(age);
commit;

# 5.   1   
select * from test where age = 22 for update;

# 6.   2   
select * from test where age = 21 for update;
commit;

##       2      

# 7.   1    rollback
rollback;

# 8.          
set autocommit = 1;


悲観ロックの弱体化バージョン
悲観的なロックはselect...lock in share modeを用いて実現することもできるが、select...for updateに比べて前者はクエリをブロックしない.前者はIS(意向共有ロック)ロックを使用する、後はIX(意向排他ロック)ロックを使用するためである.次に、select...lock in share modeを検証します.
# 1.           
set autocommit = 0;

# 2.   1   
select * from test where id = 1 lock in share mode; 

# 3.   2   
select * from test where id = 1 lock in share mode;  
commit;

##       2      

# 4.   2   
update test set age = 23 where id = 1;
commit;
 
##       2     update  

# 5.   1   rollback;
rollback;

##       2       

# 6.          
set autocommit = 1;


楽観ロック
楽観ロックの大部分はバージョンメカニズム(VersionまたはTimestamp)に基づいて実現され、相対的に悲観ロックはより緩やかであり、多くの場合、悲観ロックよりも同時的に高いため、開発の実際の運用は楽観ロックに近い.
楽観的ロックの実現
# 1.      ,   version   
ALTER table test add version int not null;

# 2.           
set autocommit = 0;

# 3.   1   
select * from test where id = 1 ; 

##       2 version     0

# 4.   2   
select * from test where id = 1;

##       2 version     0

# 5.   1   
update test set age = 24 , version = version+1 where id = 1 and version = 0;
commit;

##       1       

# 6.   2   
update test set age = 24 , version = version+1 where id = 1 and version = 0;
commit;

##       2     ,           0.

# 7.          
set autocommit = 1;
commit;

楽観的なロックの使用推奨事項
楽観ロックが使用する場合、必ずしも同じトランザクションにあるとは限らず、versionフィールドの更新時に読み取り時の値と一致しているかどうかを検出し、一致している場合は更新し、そうでない場合は更新に失敗する.現在、多くのormにversionの自動更新を実現する機能がある、使い勝手が非常に便利であり、この方式での同時処理も推奨されている.