次の perl コードを検討してください。
$schema->txn_begin();
my $r = $schema->resultset('test1')->find({id=>20});
my $n = $r->num;
$r->num($n+1);
print("updating for $$\n");
$r->update();
print("$$ val: ".$r->num."\n");
sleep(4);
$schema->txn_commit();
更新はトランザクションによって保護されているため、2 つのプロセスが「num」フィールドを更新しようとすると、2 つ目のプロセスは競合に負けたため、何らかのエラーで失敗するはずです。Interbase では、これを「デッドロック」エラーと呼んでいます。ただし、MySQL は update() 呼び出しで一時停止しますが、最初の呼び出しが commit を呼び出した後は喜んで続行します。2 番目のプロセスは num の「古い」値を持つため、インクリメントが正しくありません。観察:
$ perl trans.pl & sleep 1 ; perl trans.pl
[1] 5569
updating for 5569
5569 val: 1015
updating for 5571
5571 val: 1015
[1]+ Done perl trans.pl
どちらの場合も、結果の値は「1015」です。これはどのように正しいのでしょうか?