async-lockを使った排他制御

async-lockを使ってサーバサイドで排他制御させる方法です。排他制御を使えば同時アクセスよるデータの不整合を防げます。本記事で扱うモジュールのバージョンは次のとおりです。

  • Node.js - 14.16.0
  • express - 4.17.1
  • async-lock - 1.3.0

インストール

次のコマンドを実行します。

npm install async-lock

以降は使い方になります。

execute function を使う場合

コールバック関数を抜けてからロックが解放されます。execute functionでのエラーをコールバック関数で判定する必要があります。

実行結果

node async-lock-sample-execute.jsを実行し、ブラウザから/start-lock > /start-lock2の順に実行した場合の実行結果(ログ)です。

1620694694502 execute
1620694699510 sleep end
1620694699511 start-lock execute end.
1620694699511 response send start.
1620694699513 response send end.
1620694699514 execute
1620694704513 sleep end
1620694704514 start-lock2 execute end.
1620694704514 response send start.
1620694704515 response send end.

エラーを発生させる

execute functionでエラーを発生させたい場合は次のようにdone()を実行します。

done(new Error('test exception.'));

エラー発生時の実行結果

execute functionでエラーを発生させた場合の実行結果です。

1620694953006 execute
1620694958010 sleep end
1620694958012 start-lock execute end.
test exception.
1620694958023 execute
1620694963027 sleep end
1620694963029 start-lock2 execute end.
test exception.

Promise を使う場合

then()またはcatch()がコールされるタイミングでロックは解除されます。

実行結果

node async-lock-sample-promise.jsを実行し、ブラウザから/start-lock > /start-lock2の順に実行した場合の実行結果(ログ)です。

1620696446739 execute
1620696451755 sleep end
1620696451757 execute
1620696451758 start-lock execute end.
1620696451758 response send start.
1620696451765 response send end.
1620696456764 sleep end
1620696456765 start-lock2 execute end.
1620696456765 response send start.
1620696456766 response send end.

コールバック関数のみの場合

ロック解除のタイミングはPromiseを使う場合と変わりません。

実行結果

node async-lock-sample-only-callback.jsを実行し、ブラウザから/start-lock > /start-lock2の順に実行した場合の実行結果(ログ)です。

1620698092689 execute
1620698097698 sleep end
1620698097700 execute
1620698097701 start-lock execute end.
1620698097702 response send start.
1620698097721 response send end.
1620698102703 sleep end
1620698102704 start-lock2 execute end.
1620698102704 response send start.
1620698102705 response send end.

ロック処理内でのエラーについて

execute functionを使う場合、Promiseを使う場合、コールバック関数のみの場合問わず、ロック処理内でエラーを発生させたい場合は次のようにdone()を実行します。

done(new Error('test exception.'));

次のようにthrowを使うとすると実行エラーになるので注意してください。

throw new Error('test exception.');
このエントリーをはてなブックマークに追加
にほんブログ村 IT技術ブログへ

コメント

メールアドレスが公開されることはありません。 が付いている欄は必須項目です