트랜잭션은 데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 단위이다.
성질
Atomicity - 원자성
트랜잭션의 연산은 데이터베이스에 모두 반영, 혹은 반영되지 않아야 한다.
트랜잭션 내의 모든 명령이 완벽히 수행되어야 하며, 무엇 하나라도 오류가 발생하면 전부 취소되어야한다.
Consistency - 일관성
트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다.
트랜잭션이 진행되는 동안 데이터베이스가 변경되어도 업데이트된 데이터베이스로 트랜잭션이 진행되는 것이 아니라 처음 트랜잭션을 실행할 때의 참조한 데이터베이스로 진행된다.
Isolation - 독립성
둘 이상의 트랜잭션이 동시에 실행될 경우 어느 하나의 트랜잭션이 다른 트랜잭션의 연산에 관여할 수 없다.
Durablility - 지속성
성공적으로 완료된 트랜잭션의 결과는 영구적으로 반영되어야 한다.
트랜잭션 연산
Commit 연산
Commit은 하나의 트랜잭션이 성공적으로 끝났고, 데이터베이스가 일관된 상태에 있을 때, 트랜잭션이 완료됐다는 것을 알려주는 연산이다.
Rollback 연산
Rollback은 하나의 트랜잭션 처리가 비정상적으로 종료되어 트랜잭션의 일관성이 깨진 경우 트랜잭션의 원자성을 구현하기 위해 트랜잭션이 행한 모든 연산을 취소하는 연산이다.
MemberServiceV3_1
private final PlatformTransactionManager transactionManager;
private final MemberRepositoryV3 memberRepository;
public void accountTransfer(String fromId, String toId, int money) throws SQLException {
//트렌잭션 시작
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
//비즈니스 로직
bizLogic(fromId, toId, money);
transactionManager.commit(status);//성공시 커밋
} catch (Exception e) {
transactionManager.rollback(status);//실패시 롤백
throw new IllegalStateException(e);
}
}
private void bizLogic(String fromId, String toId, int money) throws SQLException {
Member fromMember = memberRepository.findById(fromId);
Member toMember = memberRepository.findById(toId);
memberRepository.update(fromId, fromMember.getMoney() - money);
validation(toMember);
memberRepository.update(toId, toMember.getMoney() + money);
}
private void validation(Member toMember) {
if (toMember.getMemberId().equals("ex")) {
throw new IllegalStateException("이체중 예외 발생");
}
}
MemberServiceV3_2
private final TransactionTemplate txTemplate;
private final MemberRepositoryV3 memberRepository;
public MemberServiceV3_2(PlatformTransactionManager transactionManager, MemberRepositoryV3 memberRepository) {
this.txTemplate = new TransactionTemplate(transactionManager);
this.memberRepository = memberRepository;
}
public void accountTransfer(String fromId, String toId, int money) throws SQLException {
txTemplate.executeWithoutResult((status) -> {
//비즈니스 로직
try {
bizLogic(fromId, toId, money);
} catch (SQLException e) {
throw new IllegalStateException(e);
}
});
}
private void bizLogic(String fromId, String toId, int money) throws SQLException {
Member fromMember = memberRepository.findById(fromId);
Member toMember = memberRepository.findById(toId);
memberRepository.update(fromId, fromMember.getMoney() - money);
validation(toMember);
memberRepository.update(toId, toMember.getMoney() + money);
}
private void validation(Member toMember) {
if (toMember.getMemberId().equals("ex")) {
throw new IllegalStateException("이체중 예외 발생");
}
}
MemberServiceV3_3
private final MemberRepositoryV3 memberRepository;
@Transactional
public void accountTransfer(String fromId, String toId, int money) throws SQLException {
bizLogic(fromId, toId, money);
}
private void bizLogic(String fromId, String toId, int money) throws SQLException {
Member fromMember = memberRepository.findById(fromId);
Member toMember = memberRepository.findById(toId);
memberRepository.update(fromId, fromMember.getMoney() - money);
validation(toMember);
memberRepository.update(toId, toMember.getMoney() + money);
}
private void validation(Member toMember) {
if (toMember.getMemberId().equals("ex")) {
throw new IllegalStateException("이체중 예외 발생");
}
}
'데이터베이스' 카테고리의 다른 글
DataSource와 커넥션 풀 (0) | 2023.03.05 |
---|---|
JDBC 등록, 조회, 수정, 삭제 (0) | 2023.03.05 |