티스토리 뷰

데이터베이스/JDBC

[JDBC] 트랜잭션

거북이의 기술블로그 2024. 11. 5. 00:39
1. 트랜잭션 ACID
2. 트랜잭션 격리 수준
3. DB 세션
4. 트랜잭션 직접 구현

 

트랜잭션 ACID

  • 원자성 (Atomicity)
    • 트랜잭션 내에서 실행한 작업들은 모두 성공하거나 모두 실패
  • 일관성 (Consistency)
    • 일관성 있는 데이터베이스 상태 유지 (무결성 제약 조건을 항상 만족)
  • 격리성 (Isolation)
    • 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않아야함
  • 지속성 (Durability)
    • 트랜잭션을 성공적으로 끝내면 그결과가 항상 기록되어야함

 

트랜잭션 격리 수준

  • READ UNCOMMITED (커밋되지 않은 읽기)
  • READ COMMITTED (커밋된 읽기)
  • REPEATABLE READ (반복 가능한 읽기)
  • SERIALIZABLE (직렬화 가능)
일반적으로, READ COMMITED(커밋된 읽기)가 기본적으로 사용된다

 

 

DB 세션

  • 데이터베이스는 내부적으로 커넥션 요청에따른 세션을 유지하게 된다.
  • 일반적으로 조회의 경우, 트랜잭션이 필요 없을수 있지만 "수정/삭제/생성"에 있어서는 유지되어야하기에 세션A와 세션B가 작업적으로 독립적이어야 한다

  • 커밋이 아직 안되었기에, 세션 B는 B의 정보가 조회가 되지 않는다 (트랜잭션이 지켜지는 중)

 

트랜잭션 직접 구현

보통 Sql의 경우, 쿼리와 동시에 Commit이 진행된다 ( AutoCommit 모드 )
따라서, 원활한 트랜잭션 실습을 위해서는 AutoCommit 모드를 해제해야한다
  • AutoCommit이 해제되었다는 가정하에, Commit하기 전까지는 해당 세션은 Lock을 획득하게 된다
    • 다른 세션에서 (세션B), 값을 변경을 위해서는 해당 Lock을 대기해야하는 상황이 발생한다 ( 트랜잭션 )
    • 세션A가 Commit을 진행해야 비로소 세션B가 값 변경을 진행할 수 있다

 //RepositoryV1
 public void update(Connection con,String memberId, int money) throws SQLException{
        String sql = "update member set money=? where member_id=?";


        PreparedStatement pstmt = null;

        try{
            pstmt  = con.prepareStatement(sql);
            pstmt.setInt(1,money);
            pstmt.setString(2, memberId);

            int resultSize = pstmt.executeUpdate();
            log.info("업데이트 행 개수  = {}", resultSize);
        }catch(SQLException e){
            log.error("db error", e);
            throw e;
        }finally{
            close(null,pstmt,null);
        }
    }

public Member findById(Connection con, String memberId) throws SQLException{
        String sql = "select * from member where member_id=?";

        PreparedStatement pstmt = null;
        ResultSet rs = null;

        try {
            pstmt = con.prepareStatement(sql);
            pstmt.setString(1, memberId);

            rs = pstmt.executeQuery();
            if (rs.next()) {
                Member member = new Member();
                member.setMemberId(rs.getString("member_id"));
                member.setMoney(rs.getInt("money"));
                return member;
            } else {
                throw new NoSuchElementException("member not found memberId=" + memberId);
            }
        }catch (SQLException e){
            log.error("db error", e);
            throw e;
        }finally{
            close(null, pstmt, rs);
        }
    }


//Connection 유지
public void accountTransfer(String fromId, String toId, int money) throws SQLException{
        Connection con = dataSource.getConnection();
        try{
            con.setAutoCommit(false);
            Member fromMember = memberRepositoryV1.findById(fromId);
            Member toMember = memberRepositoryV1.findById(toId);

            memberRepositoryV1.update(con, fromId, fromMember.getMoney() - money);
            if (toMember.getMemberId().equals("ex")){
                throw new IllegalStateException("이체중 예외발생");
            }
            memberRepositoryV1.update(con, toId, toMember.getMoney() + money);
            con.commit();
        }catch(Exception e){
            con.rollback();
            throw new IllegalStateException(e);
        }finally {
            if (con != null) {
                try {
                    con.setAutoCommit(true); //커넥션 풀 고려 
                    con.close(); // 여기서 해제
                } catch (Exception e) {
                    log.info("error", e);
                }
            }
        }
    }
    
    
    
    @Test
    memberService = new MemberServiceV2(dataSource, memberRepository);
  • 장점
    • Connection을 유지해서 트랜잭션 수행이 가능해졌다 (AutoCommit : false, con.commit())
    • 세션 락을 자연스럽게 사용
  • 단점
    • 코드가 복잡하다 (서비스 계층이 복잡해진다)
    • connection close()를 신경써서 해야한다
    • AutoCommit모드를 껐다 켰다 반복해야한다

 

'데이터베이스 > JDBC' 카테고리의 다른 글

[JDBC] 트랜잭션 템플릿  (1) 2024.11.06
[JDBC] 트랜잭션 매니저  (0) 2024.11.05
[JDBC] 커넥션 풀  (7) 2024.11.04
[JDBC] JDBC CRUD 구축  (1) 2024.10.31
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함