programing

Springbean에서 새로운 거래를 시작하고 있습니다.

muds 2023. 8. 9. 21:05
반응형

Springbean에서 새로운 거래를 시작하고 있습니다.

다음이 있습니다.

@Transactional(propagation = Propagation.REQUIRED)
public class MyClass implementes MyInterface { ...

에는 MyInterface라는 메서드가 .go().

go()가 실행되면 메소드가 완료되면 커밋/롤백하는 새 트랜잭션을 시작합니다. 이것은 괜찮습니다.

이제 시작()을 MyClass에서 다음과 같은 개인 메서드라고 부릅니다.@Transactional(propagation = Propagation.REQUIRES_NEWSpring은 REQUEST_NEW 주석을 "무시"하고 새 트랜잭션을 시작하지 않는 것 같습니다.가은이 Spring AOP인터벨레스이페 (MyInterface)에서 작동하고 MyClass 메서드에 대한 호출을 가로채지 않기 때문이라고 생각합니다.이거 맞는건가요?

go() 트랜잭션 내에서 새로운 트랜잭션을 시작할 수 있는 방법이 있습니까?트랜잭션이 REQUESTESS_NEW로 구성된 다른 Spring 관리 빈을 호출하는 유일한 방법입니까?


업데이트: 클라이언트가 실행될 때 추가go()클래스가 아닌 인터페이스에 대한 참조를 통해 이 작업을 수행합니다.

@Autowired
MyInterface impl;

impl.go();

Spring 참조 2.5에서:

프록시를 사용하는 경우@Transactional주석은 공개 가시성이 있는 메서드에만 적용해야 합니다., 메서드 또는 메서드에 않은 에는 다음과 같이 합니다.@Transactional주석, 오류는 발생하지 않지만 주석이 달린 메서드는 구성된 트랜잭션 설정을 표시하지 않습니다.

Spring은 무시합니다.@Transactional비공용 메서드에 대한 주석입니다.

또한.

프록시 모드(기본값)에서는 프록시를 통해 들어오는 '외부' 메서드 호출만 가로채게 됩니다. ' 객체의 가 즉, '체호출자', 즉상내대로 되어 있어도 트랜잭션으로 @Transactional!

그래서 당신이 당신의 방법을 만들더라도.public같은 클래스의 메서드 내에서 호출하면 새 트랜잭션이 시작되지 않습니다.

사용할 수 있습니다.aspectj클래스에서 트랜잭션 관련 코드가 짜여지고 런타임에 프록시가 생성되지 않도록 트랜잭션 설정의 모드입니다.

자세한 내용은 참조 문서를 참조하십시오.

이를 수행하는 또 다른 가능한 방법은 클래스 자체에서 클래스의 스프링 프록시를 가져오는 것과 그것에 대한 호출 메서드를 가져오는 것입니다.this:

@Service
@Transactional(propagation = Propagation.REQUIRED)
public class SomeService {

    @Autowired
    private ApplicationContext applicationContext;

    private SomeService  getSpringProxy() {
        return applicationContext.getBean(this.getClass());
    }

    private void doSomeAndThenMore() {
        // instead of
        // this.doSometingPublicly();
        // do the following to run in transaction
        getSpringProxy().doSometingPublicly();
    }

    public void doSometingPublicly() {
        //do some transactional stuff here
    }

}

@Transactional표시되는 경우에만 알 수 있습니다.publicSpring AOP의 작동 방식으로 인해 방법이 변경되었습니다.

그러나 원하는 경우 다음을 사용하여 새 트랜잭션을 프로그래밍 방식으로 시작할 수 있습니다.TransactionTemplate,예.

TransactionTemplate txTemplate = new TransactionTemplate(txManager);                
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
txTemplate.execute(status -> {
        // do stuff
});

즉, 트랜잭션 동작을 수행하려면 메서드를 프록시를 통해 호출해야 합니다.질문과 같이 동일한 빈에 "REQUEES_NEW"를 호출할 수 있습니다.그러기 위해서는 "자신"을 언급해야 합니다.봄에는 그것이 직접적으로 가능하지 않습니다.@Resource 주석을 삽입해야 합니다.

@Service("someService")
public class ServieImpl implements Service {

   @Resource(name = "someService")
   Service selfReference;

   @Transactional
   public void firstMethod() {
       selfReference.secondMethod();
   }

   @Transactional(propagation = Propagation.REQUIRES_NEW) 
   public void secondMethod() {    
         //do in new transaction
   }

} 

firstMethod의 호출은 "REQUESTIES_NEW" 트랜잭션이 작동하도록 하는 "이것"이 아닌 프록시를 호출합니다.

언급URL : https://stackoverflow.com/questions/3037006/starting-new-transaction-in-spring-bean

반응형