[SPRING] Spring @ 여러 데이터 소스 간의 트랜잭션과 트랜잭션
SPRINGSpring @ 여러 데이터 소스 간의 트랜잭션과 트랜잭션
하나의 트랜잭션의 일부로 두 개의 데이터 소스를 업데이트해야합니다. 그건 -
DB2에서 업데이트가 실패하면 DB1과 DB2를 모두 롤백하여 롤백하려고합니다. @Transactional을 사용하여이 작업을 수행 할 수 있습니까?
다음은 샘플 코드입니다.
@Transactional(value="db01TransactionManager")
public void updateDb01() {
Entity01 entity01 = repository01.findOne(1234);
entity01.setName("Name");
repository01.save(entity01);
//Calling method to update DB02
updateDb02();
}
@Transactional(value="db02TransactionManager")
public void updateDb02() {
Entity02 entity02 = repository02.findOne(1234);
entity02.setName("Name");
repository02.save(entity02);
//Added this to force a roll back for testing
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
내 문제는 updateDb02의 setRollbackOnly ()가 Db01 트랜잭션 만 롤백한다는 것입니다.
해결법
-
==============================
1.ChainedTransactionManager를 사용하여이 문제를 해결했습니다. - http://docs.spring.io/spring-data/commons/docs/1.6.2.RELEASE/api/org/springframework/data/transaction/ChainedTransactionManager.html
ChainedTransactionManager를 사용하여이 문제를 해결했습니다. - http://docs.spring.io/spring-data/commons/docs/1.6.2.RELEASE/api/org/springframework/data/transaction/ChainedTransactionManager.html
스프링 부트 구성 :
@Bean(name = "chainedTransactionManager") public ChainedTransactionManager transactionManager(@Qualifier("primaryDs") PlatformTransactionManager ds1, @Qualifier("secondaryDs") PlatformTransactionManager ds2) { return new ChainedTransactionManager(ds1, ds2); }
그리고 다음과 같이 사용할 수 있습니다 :
@Transactional(value="chainedTransactionManager") public void updateDb01() { Entity01 entity01 = repository01.findOne(1234); entity01.setName("Name"); repository01.save(entity01); //Calling method to update DB02 updateDb02(); } public void updateDb02() { Entity02 entity02 = repository02.findOne(1234); entity02.setName("Name"); repository02.save(entity02); //Added this to force a roll back for testing TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); }
-
==============================
2.가장 좋은 방법은 @Transactional로 주석 처리되는 세 번째 메서드를 만드는 것입니다.
가장 좋은 방법은 @Transactional로 주석 처리되는 세 번째 메서드를 만드는 것입니다.
@Transactional(readOnly = false) public void updateCommon(){ upbateDb01(); upbateDb02(); }
스프링 문서에 따르면 firts 주석이 나타날 때 트랜잭션 제어가 시작되므로이 경우 updateCommon이 호출 될 때 단일 트랜잭션이 시작됩니다. 최신 정보 하지만 CrudRepository 나 그와 비슷한 것을 사용한다면이 방법이 효과적입니다.
다중 데이터 소스의 경우 글로벌 트랜잭션 관리 개념을 사용하려고 시도 할 수 있습니다. 다음은 봄 문서의 샘플입니다.
@Inject private PlatformTransactionManager txManager; TransactionTemplate template = new TransactionTemplate(this.txManager); template.execute( new TransactionCallback<Object>(){ public void doInTransaction(TransactionStatus status){ // work done here will be wrapped by a transaction and committed. // the transaction will be rolled back if // status.setRollbackOnly(true) is called or an exception is thrown } });
링크는 다음과 같습니다. http://spring.io/blog/2011/08/15/configuring-spring-and-jta-without-full-java-ee/ 나는 그것을 스스로 사용하지 않았으므로이 주제를 깊이 탐구하지 않았다. 희망이 도움이 될 것입니다.
-
==============================
3.그것을 알아 냈다.
그것을 알아 냈다.
메소드는 다른 트랜잭션 관리자를 사용할 수 있도록 다른 bean에 있어야합니다.
-
==============================
4.나는 당신이 아래처럼 당신의 txns를 정의했다고 믿습니다.
나는 당신이 아래처럼 당신의 txns를 정의했다고 믿습니다.
@Bean(name="db01TransactionManager") @Autowired DataSourceTransactionManager tm1(@Qualifier ("datasource1") DataSource datasource) { DataSourceTransactionManager txm = new DataSourceTransactionManager(datasource); return txm; } @Bean(name="db02TransactionManager") @Autowired DataSourceTransactionManager tm2(@Qualifier ("datasource2") DataSource datasource) { DataSourceTransactionManager txm = new DataSourceTransactionManager(datasource); return txm; }
이제 가장 간단한 방법은 두 가지 트랜잭션 모두를 시도하고 catch하고 롤백하는 것입니다. 그러나 여전히 위임하기를 원할 경우 아래에 주어진 옵션이 있습니다.
자신 만의 롤백 메서드를 만들고이를 사용하십시오.
@Bean(name=“allTransactionManager") @Autowired DataSourceTransactionManager tm2(@Qualifier ("datasource1”) DataSource datasource1, @Qualifier ("datasource2") DataSource datasource2) { DataSourceTransactionManager txm = new MyDataSourceTransactionManager(datasource1,datasouce2); return txm; }
그리고 자신의 transactionmanager를 다음과 같이 정의하십시오.
MyDataSourceTransactionManager extends DataSourceTransactionManager{ DataSourceTransactionManager tm1; DataSourceTransactionManager tm2; MyDataSourceTransactionManager(Datasource ds1,Datasource d2){ tm1 = new DataSourceTransactionManager(DataSource); tm2 =new DataSourceTransactionManager(DataSource); } // override and for roll back, rollback for both of tm1 and tm2. Thus all actions are delegated in this class }
그런 다음 동 기적으로 작업하려는 모든 위치에서 DAO 계층에 사용하십시오.
@Transactional("allTransactionManager")
이제는 두 가지 유형의 트랜잭션에 대해 롤백 또는 커밋 할 수있는 고유 한 트랜잭션 관리자가 있습니다.
from https://stackoverflow.com/questions/48954763/spring-transactional-with-a-transaction-across-multiple-data-sources by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] JBoss EAP 6.1에서 스프링 부트 배포 (0) | 2019.07.13 |
---|---|
[SPRING] 청소기 API에서 기본 기본 오류 컨트롤러 방지 [duplicate] (0) | 2019.07.12 |
[SPRING] 메타 데이터 용 내장 데이터베이스와 다른 데이터 용 두 번째 데이터베이스를 사용하는 Java Spring Batch (0) | 2019.07.12 |
[SPRING] @Document 주석의 MongoDB 및 SpEL 표현식 (0) | 2019.07.11 |
[SPRING] Spring Security maxSession이 작동하지 않습니다. (0) | 2019.07.11 |