====== Programmatic Transaction Management ====== ===== 개요 ===== 프로그램에서 직접 트랜잭션을 관리하고자 할 때 사용할 수 있는 방법에 대해서 설명하고자 한다. **TransactionTemplate를 사용하는 방법**과 **Trnasaction Manager를 사용하는 방법** 두가지가 있다. ===== 설명 ===== ==== TransactionTemplate를 사용하는 방법 ==== TransactionTemplate를 정의하고 callback 메소드 정의를 이용하여 Transaction 관리를 할 수 있도록 하는 방법이다. === Configuration === ^ PROPERTIES ^ 설 명 ^ |transactionManager| 트랜잭션매니저 | |dataSource| 데이타소스 | 위의 설정에서 transactionTemplate를 정의하고 property로 transactionManager을 정의한다. Templeate를 이용한 샘플은 아래와 같다. === Sample Source === @Test public void testInsertCommit() throws Exception { transactionTemplate.execute(new TransactionCallbackWithoutResult() { public void doInTransactionWithoutResult(TransactionStatus status) { try { Role role = new Role(); role.setRoleId("ROLE-001"); role.setRoleName("ROLE-001"); role.setRoleDesc(new Integer(1000)); roleService.createRole(role); } catch (Exception e) { status.setRollbackOnly(); } } }); Role retRole = roleService.findRole("ROLE-001"); assertEquals("roleName Compare OK",retRole.getRoleName(),"ROLE-001"); } 위의 예에서 transactionTemplate.execute에 TransactionCallbackWithoutResult를 정의하여 Transaction 관리를 하는 것을 확인할 수 있다. === 사용 방법 === Transaction Context에 의해 호출될 callback 메소드를 정의하고 이 메소드 내에 비즈니스 로직을 구현해주면 된다. 아래는 사용하는 방법의 예이다 this.transactionTemplate.execute(new TransactionCallbackWithoutResult() { public void doInTransactionWithoutResult(TransactionStatus status) { //... biz. logic ... }}); this.transactionTemplate.execute(new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { //... biz. logic ... }}); } callback 메소드 doInTransactionWithoutResult()는 Result 값이 없을 경우에 사용하고, Result 값이 존재하는 경우에는 doInTransaction()으로 사용하도록 한다. 또한, callback 메소드 내에서 입력 인자인 TransactionStatus 객체의 setRollbackOnly() 메소드를 호출함으로써 해당 Transaction을 rollback할 수 있다. ==== Trnasaction Manager를 사용하는 방법 ==== Transaction Manager를 직접 이용하는 방법이다. === Configuration === ^ PROPERTIES ^ 설 명 ^ |dataSource| 데이타소스 | 위의 설정에서 transactionManager을 정의한다. === Sample Source === @Test public void testInsertRollback() throws Exception { int prevCommitCount = roleService.getCommitCount(); int prevRollbackCount = roleService.getRollbackCount(); DefaultTransactionDefinition txDefinition = new DefaultTransactionDefinition(); txDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus txStatus = transactionManager.getTransaction(txDefinition); try { Role role = new Role(); role.setRoleId(Thread.currentThread().getName() + "-roleId"); role.setRoleName(Thread.currentThread().getName() + "-roleName"); role.setRoleDesc(new Integer(1000)); roleService.createRole(role); roleService.createRole(role); transactionManager.commit(txStatus); } catch (Exception e) { transactionManager.rollback(txStatus); } finally { assertEquals(prevCommitCount, roleService.getCommitCount()); assertEquals(prevRollbackCount + 2, roleService.getRollbackCount()); } } Transaction 서비스를 직접 얻어온 후에 위와 같이 try~catch 구문 내에서 Transaction 서비스를 이용하여, 적절히 begin, commit, rollback을 수행한다. 이 때, TransactionDefinition와 TransactionStatus 객체를 적절히 이용하면 된다. ===== 잠고자료 =====