참고 : 스프링 3.x 트랜잭션

In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.



질문

////////////////////////////// 

//예제소스 

////////////////////////////// 

@Service("testService") 

public class TestServiceImpl extends AbstractServiceImpl implements TestService 

@Resource(name = "testDao") 

private TestDao testDao; 


@Transactional(propagation = Propagation.REQUIRES_NEW) 

@Override 

public void txTest() 

HashMap<String, String> data01 = new HashMap<String, String>(); 

data01.put("ID", "0000001"); 

data01.put("NAME", "스파이더맨"); 

testDao.createTest01(data01); 


@Transactional(propagation = Propagation.REQUIRES_NEW) 

@Override 

public void txTest1() 

HashMap<String, String> data02 = new HashMap<String, String>(); 

data02.put("ID", "0000002"); 

data02.put("NAME", "배트맨"); 

testDao.createTest01(data02); 


HashMap<String, String> data01 = new HashMap<String, String>(); 

data01.put("ID", "0000001"); 

data01.put("NAME", "스파이더맨"); 

testDao.createTest01(data01); 


@Transactional 

@Override 

public void txTest2() 

txTest(); 

txTest1(); 


# 현재 상황 

ID 는 등록하고자 하는 테이블의 KEY 로 중복 등록 하면 예외가 발생 합니다.


Controller 에서 txTest 와 txTest1 을 따로 호출 하면 스파이더맨만 등록이 되고 배트맨은 등록이 안되는 원하는 결과를 얻을 수 있습니다. 


Controller 에서 txTest2를 호출 하면 모두 등록이 안되고 있습니다. (호출한 두 메소드 전체에 걸쳐 트랜잭션 적용됨) 


txTest2 에서 @Transactional 을 제거 하고 호출 하면 스파이더맨과 배트맨이 모두 등록이 됩니다. (트랜잭션 적용 안됨) 


txTest2 의 @Transactional 을 @Transactional(propagation = Propagation.REQUIRES_NEW) 로 변경해 보았는데 호출한 두 메소드 전체에 걸쳐 트랜잭션이 적용 됩니다. 


# 질문 

Controller 에서 txTest2 메소드를 호출 하여 

txTest() 에서 등록 된 값은 commit 이 되고 

txTest1() 에서 등록 된 값은 rollback 이 되게 하고 싶습니다. 

(스파이더맨만 등록이 되고 배트맨은 등록이 안되는 원하는 결과) 

방법이 없나요?


답변

안녕하세요. 표준프레임워크센터입니다.


Transactional은 Proxy기반으로 동작하기 때문에 직접호출(자기 호출)은 Transaction이 적용되지 않습니다.


즉, txTest2메소드에서 txTest, txTest1을 직접 호출하는 방식으로는 두 메소드의 Transaction이 먹지 않습니다.


처음에 하셨던것처럼 Controller를 통해 txTest, txTest1을 호출하시거나


txTest, txTest1 메소드를 외부 클래스로 빼서(인터페이스 기반이어야합니다) txTest2에서 호출하는 방식으로 


Transaction을 적용하시기 바랍니다.


감사합니다.


이걸 몰라서 한참 헤메었다.

+ Recent posts