SELECT FOR UPDATE文のタイムアウトを指定し、タイムアウトが発生した場合にtry-catchブロックを使用してリトライする。
1.SELECT FOR UPDATE文のタイムアウト時間を指定する
SELECT * FROM your_table
WHERE your_condition
FOR UPDATE WAIT 1;
2.リトライロジックを実装する
PessimisticLockingFailureExceptionが発生した場合、最大3回までリトライし、リトライ間隔は0.5秒を設定する。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.PessimisticLockingFailureException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class YourEntityService {
@Autowired
private YourEntityRepository repository;
@Transactional
public void updateEntity(Long id, String newData) {
int maxRetries = 3; // 最大3回までリトライ
int retryCount = 0;
boolean success = false;
while (!success && retryCount < maxRetries) {
try {
YourEntity entity = repository.findByIdForUpdate(id);
if (entity != null) {
entity.setData(newData);
repository.save(entity);
success = true;
}
} catch (PessimisticLockingFailureException e) {
retryCount++;
if (retryCount >= maxRetries) {
throw e; // リトライ回数を超えた場合は例外を再スロー
}
try {
Thread.sleep(500); // 0.5秒待機してからリトライ
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("Thread was interrupted", ie);
}
}
}
}
}