Springbean에서 새로운 거래를 시작하고 있습니다.
다음이 있습니다.
@Transactional(propagation = Propagation.REQUIRED)
public class MyClass implementes MyInterface { ...
에는 MyInterface라는 메서드가 .go()
.
go()가 실행되면 메소드가 완료되면 커밋/롤백하는 새 트랜잭션을 시작합니다. 이것은 괜찮습니다.
이제 시작()을 MyClass에서 다음과 같은 개인 메서드라고 부릅니다.@Transactional(propagation = Propagation.REQUIRES_NEW
Spring은 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
표시되는 경우에만 알 수 있습니다.public
Spring 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
'programing' 카테고리의 다른 글
Pylint의 Cell-var-from-loop 경고 (0) | 2023.08.09 |
---|---|
Spring Framework에서 주석을 사용하여 빈 이름을 설정할 수 있습니까? (0) | 2023.08.09 |
NodeJS를 통해 엔드포인트로 Ajax 요청을 작성하는 방법 (0) | 2023.08.09 |
scanf() 형식 문자열에서 후행 공백의 영향은 무엇입니까? (0) | 2023.08.09 |
십진수를 분수로 변환하는 방법은 무엇입니까? (0) | 2023.08.09 |