SELECT * FROM account WHERE id = 1 FOR UPDATE;위 쿼리는 id = 1 레코드에 락을 걸어 다른 트랜잭션이 읽거나 변경하지 못하도록 합니다.version 필드를 추가합니다. 업데이트 시 이 필드를 체크해 충돌을 감지합니다.@Transactional
public void updateAccount(Account account) {
Account existingAccount = accountRepository.findById(account.getId());
if (!existingAccount.getVersion().equals(account.getVersion())) {
throw new OptimisticLockingFailureException("Version mismatch!");
}
account.setVersion(account.getVersion() + 1);
accountRepository.save(account);
}UPDATE account SET balance = balance - 100 WHERE id = 1;DB 내부에서 원자성을 보장하기 때문에 안전하지만, 복잡한 연산은 비효율적일 수 있습니다.설명: Redis의 빠른 속도를 활용해 임시 데이터를 저장하고, 주기적으로 DB에 반영합니다.
사용 예: 실시간성이 덜 중요한 경우, 많은 읽기/쓰기 요청 처리.
구현:
# Redis에 임시로 값을 저장
redis.incr("user:1001:balance", 100)
# 주기적으로 Redis 값을 DB에 저장
balance = redis.get("user:1001:balance")
update_account_balance_in_db(user_id=1001, balance=balance)
redis.delete("user:1001:balance")