Spring

[Spring] Transaction(트랜잭션)

jane.dev 2021. 10. 7. 23:10
반응형
Transaction(트랜잭션)
데이터베이스를 변경하는 로직을 수행할 때 하나의 단위로 처리되어야 함을 말함

 

트랜잭션의 속성

원자성(Atomicity) 하나의 트랜잭션은 하나의 단위로 처리되며, 모든 반영이 되지 않는다면 전혀 반영되지 않아야 함
일관성(Consistency) 트랜잭션으로 처리된 데이터와 그 외의 로직으로 처리된 데이터의 결과는 차이가 없어야 함
격리성(Isolation) 트랜잭션이 처리되는 동안에는 다른 트랜잭션의 연산이 개입될 수 없으며,
처리가 완료기 전까지는 다른 트랜잭션의 수행 결과를 참조할 수 없음
영속성(Durability) 트랜잭션이 처리되면 처리 전으로 돌이킬 수 없음

 

예제

CREATE TABLE tbl_test1(
    col1 VARCHAR2(50);
);

CREATE TABLE tbl_test2(
    col2 VARCHAR2(5);
);

입력할 수 있는 문자열의 길이가 서로 다른 두개의 테이블을 생성

 

public interface Sample1Mapper{
    @Insert("INSERT INTO tbl_test1 (col1) VALUES (#{data}");
    public int insertCol1(String data);
}

public interface Sample2Mapper{
    @Insert("INSERT INTO tbl_test2 (col2) VALUES (#{data}");
    public int insertCol2(String data);
}

Sample1Mapper와 Sample2Mapper 인터페이스를 생성해 @Insert 어노테이션으로 SQL 쿼리문 작성

 

public interface SampleTxService{
    public void addData(String value);
}

두 테이블에 같은 길이의 문자열을 함께 삽입하는 서비스를 생성하기 위해 SampleTxService 인터페이스와

 

public class SampleTxServiceImpl implements SampleTxService(){
    
    @Autowired
    private Sample1Mapper mapper1;
    
    @Autowired
    private Sample2Mapper mapper2;
    
    @Override
    public void addData(String value){
        mapper1.insertCol1(value);
        mapper2.insertCol2(value);
    }
}

SampleTxService를 구현한 SampleTxServiceImpl을 작성

 

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:/src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class SampleTxServiceTests{
    
    @Autowired
    private SampleTxService service;
    
    @Test
    public void testInsert(){
        // 26 글자를 각 테이블에 삽입
    	String str = "abcdefghijklmnopqrstuvxyz";
        service.addData(str);
    }
}

 

실행해보면,

tbl_test1 테이블의 col1 컬럼(VARCHAR2(50))에는 데이터가 삽입되고,

 

tbl_test2 테이블의 col2 컬럼(VARCHAR2(5))에는 데이터가 없는 것을 확인할 수 있음

 

테이블의 데이터를 삭제하고

@Transactional 어노테이션을 사용해 트랜잭션 적용

public class SampleTxServiceImpl implements SampleTxService(){
    
    @Autowired
    private Sample1Mapper mapper1;
    
    @Autowired
    private Sample2Mapper mapper2;
    
    @Transactional
    @Override
    public void addData(String value){
        mapper1.insertCol1(value);
        mapper2.insertCol2(value);
    }
}

 

 

에러 메시지가 뜨고

 

두 테이블 모두 데이터가 삽입되지 않은 것을 확인할 수 있음