Mybatisで悲観ロックの実装方法
MyBatisでの悲観ロックの実装
悲観ロックは、データベースの行を更新する前に他のトランザクションからのアクセスを排除することで、データの整合性を保つ手法です。
MyBatisでは、悲観ロックを使用する場合、通常はSELECT ... FOR UPDATEを使用します。
以下に例を示します。
1. テーブル定義
CREATE TABLE test_table ( id INT PRIMARY KEY, value VARCHAR(255) );
2. MyBatisのMapperインターフェース
public interface TestMapper { // 悲観ロックを使用してレコードを取得 TestEntity selectForUpdate(int id); // レコードの更新 int updateTestEntity(TestEntity entity); }
3. Mapper XMLファイル
<mapper namespace="com.example.mapper.TestMapper"> <select id="selectForUpdate" resultType="com.example.domain.TestEntity"> SELECT id, value FROM test_table WHERE id = #{id} FOR UPDATE </select> <update id="updateTestEntity"> UPDATE test_table SET value = #{value} WHERE id = #{id} </update> </mapper>
4. サービスクラスでの使用例
@Service public class TestService { @Autowired private TestMapper testMapper; @Transactional public void updateEntityWithPessimisticLock(int id, String newValue) { // 悲観ロックを使用してレコードを取得 TestEntity entity = testMapper.selectForUpdate(id); // 値を更新 entity.setValue(newValue); // 更新を反映 testMapper.updateTestEntity(entity); } }
この例では、トランザクション内でselectForUpdateメソッドを使用してレコードを取得し、その後に更新を行っています。
selectはデータベースの行にロックをかけ、他のトランザクションが同じ行にアクセスするのを防ぎます。
注意点
- 悲観ロックはデータベースのパフォーマンスに影響を与える可能性があるため、適切なシナリオで使用することが重要です。
- データベースの種類や設定によっては、ロックの動作が異なる場合があります。