こんにちは、SCSK の松山です。
Amazon Aurora DSQL (以下 DSQL と略す) について、従来の PostgreSQL との差異に焦点をあてて調べてみたシリーズ、前回(第二弾)は、従来の PostgreSQL と比較した場合の機能制限についてお伝えしました。
第三弾として、本件では DSQL が採用している楽観的同時実行制御に焦点をあててまとめていきます。
※本件は 2025/2 時点の検証結果をもとに記載しています。
今後動作が変更される可能性がある旨、ご注意ください。
同時実行制御とは
実際に実機検証を行う前に、まずは同時実行制御について簡単に説明します。
同時実行制御とは、データベースが複数のトランザクション処理を同時実行する際、データの整合性を保つための制御方法です。
データベースは同時に複数のトランザクション要求を受け付けることができます。
しかし同じデータに対して複数のトランザクションから異なる更新を同時に行ってしまうと、データに矛盾が発生してしまいます。
【在庫が100個存在する商品を AさんとBさんが同時に取り出せてしまった場合】
上記のような矛盾が発生しない様に管理するのが同時実行制御です。
この際、DSQL では 主なデータベース製品 ORACLE、MySQL、PostgreSQL などとは異なる制御方法として楽観的同時接続制御が採用されています。
同時実行制御の種類
悲観的同時実行制御 (PCC)
主なデータベース製品 ORACLE、MySQL、PostgreSQL などでは悲観的同時実行制御 (PCC : Pessimistic Concurrency Control) を採用しています。「同時実行制御」とだけ記載されている場合には、主に悲観的同時実行制御を指していることが多いでしょう。
「同時にトランザクションが実行されている可能性がある」という悲観的な考え方で制御を行うため、このような名称になっています。
悲観的同時実行制御の場合は、内部的に処理に順番を割り振ります。
順番が先に割り当てられた処理が対象をロックし、後に割り当てられた処理はロックが解放されるまで待機します。ロック獲得側が処理を確定する COMMIT を行ったタイミングで更新の反映とロックの解除が行われるため、後に割り当てられた処理との整合性が保たれます。
楽観的同時実行制御 (OCC)
DSQL では楽観的同時実行制御 (OCC:Optimistic concurrency control) を採用しています。
「同時に実行しているトランザクションは存在しない」という楽観的な考え方で制御を行うため、このような名称になっています。
楽観的同時実行制御の場合は、処理実行中に矛盾が発生する更新が行われても待ちは発生しません。
かわりに処理を確定する COMMIT を行ったタイミングで、矛盾する操作が行われたかがチェックされます。
先に COMMIT した処理の更新内容に対して、後から行った処理の更新内容が矛盾している場合、エラーを返して処理の再実行を要求することで処理の整合性が保たれます。
実機検証
検証内容
- DSQL_1 Versinia 環境と DSQL_2 Ohio 環境から、同時に同一表の競合する行へ更新を行う
- DSQL_1 Versinia 環境を先に COMMIT し、DSQL_2 Ohio を COMMIT した場合の動作と表の更新状況を確認する
まとめ
楽観的同時実行制御では処理を確定する COMMIT を行ったタイミングで整合性のチェックが行われることがわかりました。
悲観的同時実行制御では何らかの理由でロックが長期間解放されない場合、後続の処理が待たされますが、楽観的同時実行制御では先に COMMIT した処理が優先されるため、待ちが発生しません。
ただし COMMIT 時に先に実行していた処理と矛盾が発生した場合には、エラーを受け処理の再実行が必要です。そのため、悲観的同時実行制御で動作していたシステムを DSQL へ移行する場合には、リトライ処理の仕組みを作りこむことが重要と言えるでしょう。
DSQL の利用ケースを検討する際に、今回の内容がお役に立てば幸いです。