[SPRING] Spring 데이터와 mongodb - @Transactional 내에서 스프링으로 간단한 롤백
SPRINGSpring 데이터와 mongodb - @Transactional 내에서 스프링으로 간단한 롤백
나는 mongodb (DocumentRepository)와 Hibernate 엔티티 (EntityRepository)를위한 2 개의 저장소를 가지고있다.
나는 간단한 서비스를 가지고있다 :
@Transactional
public doSomePersisting() {
try {
this.entityRepository.save(entity);
this.documentRepository.save(document);
}
catch(...) {
//Rollback mongoDB here
}
}
mongoDB를 "// Rollback mongoDB here"라인에서 롤백 할 수 있습니까? 이미 엔티티 부분 (트랜잭션 주석)에서 롤백을 얻었습니다.
해결법
-
==============================
1.MongoDB는 트랜잭션을 지원하지 않습니다 (적어도 단일 문서의 범위를 벗어나지는 않음). 변경 사항을 롤백하려면 직접 수정해야합니다. Mongo에서 자신의 거래를 구현하는 방법을 설명하는 몇 가지 리소스가 있습니다. 당신은 ..
MongoDB는 트랜잭션을 지원하지 않습니다 (적어도 단일 문서의 범위를 벗어나지는 않음). 변경 사항을 롤백하려면 직접 수정해야합니다. Mongo에서 자신의 거래를 구현하는 방법을 설명하는 몇 가지 리소스가 있습니다. 당신은 ..
http://docs.mongodb.org/manual/tutorial/perform-two-phase-commits/
이것은 사용할 수있는 패턴에 대한 설명 일뿐입니다. 응용 프로그램에서 트랜잭션이 절대적으로 필요하다고 판단되면 MongoDB가 사용자의 요구에 적합한 지 여부를 고려해야합니다.
-
==============================
2.내 대답을 다시 보내 주셔서 죄송합니다.
내 대답을 다시 보내 주셔서 죄송합니다.
앞의 코드는 MongoDB에 데이터를 삽입 할 수있었습니다. 심지어 쿼리 예외 (PostgreSQL에 데이터를 삽입 할 때 myBatis 사용)도 던졌습니다.
MongoDB와 관계형 데이터베이스 사이의 데이터 트랜잭션 문제를 해결했으며 @Transactional은 위의 코드에서 이러한 변경을 통해 완벽하게 작동합니다.
@Configuration public class MongoConfig extends AbstractMongoConfiguration{ private static final Logger LOG = LoggerFactory.getLogger(MongoConfig.class); @Value("${spring.data.mongodb.database}") private String dbName; @Value("${spring.data.mongodb.host}") private String dbHost; @Value("${spring.data.mongodb.port}") private int dbPort; @Override public String getDatabaseName() { return dbName; } @Bean public MongoClient mongoClient(){ return new MongoClient(dbHost, dbPort); } @Bean public MongoDbFactory mongoDbFactory(){ return new SimpleMongoDbFactory(mongoClient(),dbName); } @Bean public MongoTemplate mongoTemplate() { DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory()); MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(dbRefResolver, new MongoMappingContext()); // Don't save _class to mongo mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null)); MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(),mappingMongoConverter); mongoTemplate.setSessionSynchronization(SessionSynchronization.ON_ACTUAL_TRANSACTION); return mongoTemplate; } public MongoTemplate fetchMongoTemplate(int projectId) { DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory()); MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(dbRefResolver, new MongoMappingContext()); // Don't save _class to mongo mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null)); MongoDbFactory customizedDBFactory = new SimpleMongoDbFactory(mongoClient(), dbName+"_"+projectId); MongoTemplate mongoTemplate = new MongoTemplate(customizedDBFactory,mappingMongoConverter); MongoTransactionManager mongoTransactionManager = new MongoTransactionManager(customizedDBFactory); return mongoTemplate; } @Bean public MongoTransactionManager mongoTransactionManager() { return new MongoTransactionManager(mongoDbFactory()); } }
@Service @Component public class TestRepositoryImpl implements TestRepository{ private static final Logger LOG = LoggerFactory.getLogger(TestRepositoryImpl.class); @Autowired MongoConfig mongoConfig; @Autowired MongoTemplate mongoTemplate; @Autowired MongoTransactionManager mongoTransactionManager; @Autowired UserService userService; @Override @Transactional public void save(Test test){ int projectId = 100; if (projectId != 0) { mongoTemplate = mongoConfig.fetchMongoTemplate(100); mongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS); } mongoTemplate.insert(test); IdName idName = new IdName(); idName.setName("test"); mongoTemplate.insert(idName); User user = new User(); user.setName("Demo"); user.setEmail("srini@abspl.in"); user.setPassword("sdfsdfsdf"); userService.save(user); } }
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.abcplusd.sample.mongoapi</groupId> <artifactId>sample-mongo-api</artifactId> <version>1.0-SNAPSHOT</version> <name>Sample Spring Boot Mongo API</name> <description>Demo project for Spring Boot Mongo with Spring Data Mongo</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> <version>2.1.0.RELEASE</version> <exclusions> <exclusion> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-commons</artifactId> <version>2.1.0.RELEASE</version> </dependency> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>3.8.2</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.2.2</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
-
==============================
3.MongoDB 롤백은 @Transactional 및 MongoTransactionManager에서 작동하지 않습니다. 전체 코드 구현은 여기에 있습니다.
MongoDB 롤백은 @Transactional 및 MongoTransactionManager에서 작동하지 않습니다. 전체 코드 구현은 여기에 있습니다.
@Configuration public class MongoConfig extends AbstractMongoConfiguration{ private static final Logger LOG = LoggerFactory.getLogger(MongoConfig.class); @Value("${spring.data.mongodb.database}") private String dbName; @Value("${spring.data.mongodb.host}") private String dbHost; @Value("${spring.data.mongodb.port}") private int dbPort; @Override public String getDatabaseName() { return dbName; } @Bean public MongoClient mongoClient(){ return new MongoClient(dbHost, dbPort); } @Bean public MongoDbFactory mongoDbFactory(){ return new SimpleMongoDbFactory(mongoClient(),dbName); } @Bean public MongoTemplate mongoTemplate() { DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory()); MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(dbRefResolver, new MongoMappingContext()); // Don't save _class to mongo mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null)); MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(),mappingMongoConverter); return mongoTemplate; } public MongoTemplate fetchMongoTemplate(int projectId) { DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory()); MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(dbRefResolver, new MongoMappingContext()); // Don't save _class to mongo mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null)); MongoTemplate mongoTemplate = new MongoTemplate(new SimpleMongoDbFactory(mongoClient(), dbName+"_"+projectId),mappingMongoConverter); return mongoTemplate; } @Bean public MongoTransactionManager mongoTransactionManager() { return new MongoTransactionManager(mongoDbFactory()); } }
@Service @Component public class TestRepositoryImpl implements TestRepository{ private static final Logger LOG = LoggerFactory.getLogger(TestRepositoryImpl.class); @Autowired MongoTemplate mongoTemplate; @Autowired MongoConfig mongoConfig; //@Autowired MongoClient mongoClient; @Autowired UserService userService; @Override @Transactional public void save(Test test){ LOG.info("mongoTemplate <{}>", mongoTemplate.getDb().getName()); int projectId = 100; if (projectId != 0) { mongoTemplate = mongoConfig.fetchMongoTemplate(100); LOG.info("mongoTemplate <{}>", mongoTemplate.getDb().getName()); } //Inserting data to mongodb mongoTemplate.insert(test); IdName idName = new IdName(); idName.setName("test"); mongoTemplate.insert(idName); //Inserting data to postgreSQL User user = new User(); user.setName("Demo"); user.setEmail("XXXX@XXXX.in"); user.setPassword("sdfsdfsdf"); userService.save(user); //This line throws query exception. }
mongodb에서이 줄에서 예외를 던져도 데이터가 롤백되지 않습니다. userService.save (user); //이 줄은 삽입 쿼리 예외에서 잘못된 구문을 throw합니다.
### SQL: insert into test.user(id,name,email,password values(?,?,?,?) ### Cause: org.postgresql.util.PSQLException: ERROR: syntax error at or near "values" Position: 50 ; bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near "values" Position: 50] with root cause
from https://stackoverflow.com/questions/21386449/spring-data-and-mongodb-simple-roll-back-with-spring-within-transactional by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Aspectj 및 개인 또는 내부 메소드 가져 오기 (0) | 2019.01.18 |
---|---|
[SPRING] 데이터베이스 값을 가진 Spring 태그를 덮어 쓴다. (0) | 2019.01.18 |
[SPRING] Hibernate + Spring에서 커스텀 검증 메시지를 사용하라. (0) | 2019.01.18 |
[SPRING] 프로그래밍 방식으로 Spring Framework 작업 생성하기 (0) | 2019.01.18 |
[SPRING] 맞춤 Zuul 필터 만들기 (0) | 2019.01.18 |