[Spring] @Transactional 어노테이션 사용 및 예제!
- 웹 개발/Spring Framework
- 2019. 9. 12. 13:51
트랜잭션
- 비즈니스로직에서 쪼개질 수 없는 하나의 단위작업
- 한 번에 이루어지는 작업의 단위
- 알아두면 좋은 ACID 원칙
원자성(Atomicity) | 하나의 트랜잭션은 모두 하나의 단위로 처리해야 한다. A와 B 작업이 하나의 트랜잭션으로 묶여있는 경우 A는 성공, B는 실패할 경우 해당 작업단위는 실패로 끝나야한다. 즉, A,B 모두 rollback 되어야 한다는 원칙 |
일관성(Consistency) | 트랜잭션이 성공했다면 데이터베이스의 모든 데이터는 일관성을 유지해야한다. |
격리성(Isolation) | 트랜잭션으로 처리되는 중간에 외부에서의 간섭은 없어야한다. |
영속성(Durability) | 트랜잭션이 성공적으로 처리되면, 그 결과는 영속적으로 보관되어야 한다. |
실습했던 내용
- pom.xml 에 라이브러리 추가(transactional 관련만, dbcp, sqlSessionFactory 등의 내용은 생략.)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework-version}</version>
</dependency>
- root-context.xml 파일의 Namespaces 탭에서 'tx'항목 체크.
- root-context.xml 파일 소스에 TransactionManager 빈 등록
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven/>
- 예제 테이블 생성
* create table tbl_sample1( col1 varchar2(500));
* create table tbl_sample2( col2 varchar2(50));
> 하나의 테이블엔 500바이트, 다른 하나엔 50바이트를 줘서 대략 100정도 되는 바이트의 문자열이 들어올 경우에 대한 예제를 실행해볼것임.
//DAO 영역
public interface Sample1Mapper {
@Insert("insert into tbl_sample1 (col1) values(#{data})")
public int insertCol1(String data);
}
public interface Sample2Mapper {
@Insert("insert into tbl_sample2 (col2) values(#{data})")
public int insertCol2(String data);
}
// JUnit 으로 테스트
@Test
public void testLong() {
String str="Starry\r\n"+
"Starry night\r\n"+
"Paint your palette blue and grey\r\n"+
"Look out on a summer`s day";
log.info(str.getBytes().length);
service.addData(str);
}
위와 같은 코드가 있을 때, str 변수에는 대략 82 바이트의 길이에 해당하는 문자열이 addData() 메소드의 매개변수로 들어가면서 아래의 비즈니스 로직을 수행할 것임.
// 비즈니스 로직
@Override
public void addData(String value) {
log.info("mapper1.................");
mapper1.insertCol1(value);
log.info("mapper2.................");
mapper2.insertCol2(value);
log.info("end.....................");
}
- 위처럼 아무 트랜잭션 처리가 되지 않은 소스는 insertCol1 에서 삽입한 내용은 DB에 반영이 되고, insertCol2 에서 삽입한 내용은 DB에 반영이 되지 않음(에러가남)
- 이유는 두 작업에 대한 트랜잭션처리를 하지 않아서!!
// 비즈니스 로직(트랜잭션 처리)
@Transactional
@Override
public void addData(String value) {
log.info("mapper1.................");
mapper1.insertCol1(value);
log.info("mapper2.................");
mapper2.insertCol2(value);
log.info("end.....................");
}
- 아래와 같이 트랜잭션으로 작업단위 처리를 해놓은 경우는 두개 뿐만아니라 세개의 작업중에서도 단 하나라도 에러가나게 된다면 트랜잭션의 원칙에 따라 모두 rollback 처리되어 DB에 반영되지 않게됨.
'웹 개발 > Spring Framework' 카테고리의 다른 글
[Spring] 스프링 프레임워크 Lombok 라이브러리 (0) | 2019.10.28 |
---|---|
[Spring] Quartz 라이브러리를 이용한 스케쥴러 설정 (0) | 2019.10.04 |
[Spring framework] 스프링 MVC에서 잘 사용되는 객체, 용어 정리 (1) | 2019.09.03 |
[Spring Framework] 스프링 xml 설정을 Java 클래스로 하는 방법 (0) | 2019.09.03 |
[Spring] AOP를 이용한 로그인 인증 PointCut 예제 (2) | 2019.07.06 |