bl119.bmp[출처 : Hibernate In Action 5.1 Understanding database transactions]

트랜잭션의 특징(ACID)

■ Atomic : 트랜잭션은 하나 이상의 활동들을 묶어놓은 작업의 단위다. 원자성은 이 단위에 있는 모든 활동들이 전부 발생하거나 전부 발생하지 말아야 하는 것을 말한다. 만약 모든 활동들이 원활하게 진행되면 트랜잭션은 성공한다. 그러나 어떤 활동이라도 문제가 발생하면 롤백 하게 된다.

■ Consistent : 트랙잭션이 종료(잘 됐든 안됐든)되면, 시스템은 정상적으로 가동 되는 상태여야 한다. The data should not be corrupted with respect to reality.

■ Isolated : 트랜잭션은 여러명의 유저들이 각각 엉키지 않고 같은 데이타에 접근하는 것이 가능해야 한다. 따라서 트랜잭션은 각각에 독립적이어야 하며 같은 데이타에 동시에 읽거나 쓰는것을 방지해야 한다.(Note that isolation typically involves locking rows and/or tables in a database.) => row나 table별로 locking을 시도 한다고 한느데 이건 마치 자바에서 동기화 처리할 때 객체들의 key나 클래스의 key로 locking할 수 있는 것과 매칭이 됩니다.

■ Durable : 한번 트랜잭션이 완료되면 그 결과는 어떤 종류의 시스템 오류가 발생 하더라도 영구적으로 보존 되어야 한다. 보통 DB나 다른 종류의 Persistent 저장소에 저장하는 일을 포함한다.
[참고 : Spring In Action 5.1.1 Explaining transactions in only four words]

소스코드로 확인 하기

피자의 가격이 음수이면 UnderZeroException이 발생하도록 Pizza의 setPrice를 수정합니다.

public void setPrice(Integer price) throws UnderZeroException {
        if (price < 0) {
            throw new UnderZeroException();
        }
        this.price = price;
    }

그리고 PizzaApp 에서 setPice를 호출 하는 부분을 try-catch 블럭으로 묶습니다.[footnote]Alt + Shift + z -> y[/footnote] 그리고 catch 블럭에서 tx.rollback()을 호출합니다.
try {
            Pizza pizza = new Pizza();
            pizza.setName("Delicious");
            pizza.setPrice(-100);
            pizza.setSize("Large");
            pizza.setToping("Shrimp & Stake");
            s.save(pizza);
            tx.commit();
        } catch (UnderZeroException e) {
            tx.rollback();
            e.printStackTrace();
        } finally {
            s.close();
        }

이제 위의 트랜잭션은 롤백되서 DB에 저장되지 않습니다.