Springboot Mongo db方法不回滚事务
您好,我在代码库中使用 2 个 mongo 模板 我的代码使用 mongo 模板和 Spring 存储库 class.save() 将数据保存在 mongo db 中。在具有 @Transactional 的方法中,即使代码执行中发生一些错误,也不会回滚数据库更改。 下面是我的 mongoconfig 配置的片段
@Configuration
@EnableMongoAuditing
@EnableMongoRepositories
public class MongoConfig extends AbstractMongoClientConfiguration {
@Value("${common.db.name}")
private String dbName;
@Value("${SPRING_DATA_MONGODB_URI}")
private String dbUrl;
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
@Override
protected String getDatabaseName() {
return dbName;
}
/**
* Below bean is created as we want to make our code transactional.
* @param dbFactory
* @return
*/
@Bean(name="primaryTransactionManager")
MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
MongoTransactionManager transactionManager = new MongoTransactionManager(dbFactory);
transactionManager.setRollbackOnCommitFailure(true);
return transactionManager;
}
@Override
public MongoClient mongoClient() {
ConnectionString connectionString = new ConnectionString(dbUrl);
MongoClientSettings mongoClientSettings = MongoClientSettings.builder().applyConnectionString(connectionString).build();
return MongoClients.create(mongoClientSettings);
}
@Bean(name="primaryMongoTemplate")
public MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoClient(), getDbName());
}
}
@Configuration
@EnableMongoRepositories
public class SecondaryMongoConfig {
@Value("${common.secondary.db.name}")
private String dbName;
@Value("${COMMON_SECONDARY_SPRING_DATA_MONGODB_URI}")
private String mongoDBURI;
public String getMongoDBURI() {
return mongoDBURI;
}
public void setMongoDBURI(String mongoDBURI) {
this.mongoDBURI = mongoDBURI;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
/**
* Below bean is created as we want to make our code transactional.
* @param dbFactory
* @return
*/
@Bean(name="secondaryTransactionManager")
MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
MongoTransactionManager transactionManager = new MongoTransactionManager(dbFactory);
transactionManager.setRollbackOnCommitFailure(true);
return new MongoTransactionManager(dbFactory);
}
@Bean(name="secondaryMongoClient")
public MongoClient secondaryMongoClient() {
ConnectionString connectionString = new ConnectionString(getMongoDBURI());
MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.build();
return MongoClients.create(mongoClientSettings);
}
@Bean(name="secondaryMongoTemplate")
public MongoTemplate secondaryMongoTemplate() {
return new MongoTemplate(secondaryMongoClient(), getDbName());
}
}
下面是我用 @Transactional 注释的方法的示例代码片段
@Override
@Transactional(transactionManager = "primaryTransactionManager",rollbackFor = {Exception.class})
public String addNewRecipe() throws Exception{
RecipesDAO recipesDao = new RecipesDAO();
recipesDao.setResourceId(UUID.randomUUID().toString());
recipeRepository.save(recipesDao);
throw new Exception();
// return "dummy";
}
Hi i am using 2 mongo template in my codebase
and my code saves data in mongo db using both mongo template and Spring repository class.save() .In methods which has @Transactional doesnt rollback DB changes even if some error occurs in code execution.
Below is the snippet of my mongoconfig configurations
@Configuration
@EnableMongoAuditing
@EnableMongoRepositories
public class MongoConfig extends AbstractMongoClientConfiguration {
@Value("${common.db.name}")
private String dbName;
@Value("${SPRING_DATA_MONGODB_URI}")
private String dbUrl;
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
@Override
protected String getDatabaseName() {
return dbName;
}
/**
* Below bean is created as we want to make our code transactional.
* @param dbFactory
* @return
*/
@Bean(name="primaryTransactionManager")
MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
MongoTransactionManager transactionManager = new MongoTransactionManager(dbFactory);
transactionManager.setRollbackOnCommitFailure(true);
return transactionManager;
}
@Override
public MongoClient mongoClient() {
ConnectionString connectionString = new ConnectionString(dbUrl);
MongoClientSettings mongoClientSettings = MongoClientSettings.builder().applyConnectionString(connectionString).build();
return MongoClients.create(mongoClientSettings);
}
@Bean(name="primaryMongoTemplate")
public MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoClient(), getDbName());
}
}
@Configuration
@EnableMongoRepositories
public class SecondaryMongoConfig {
@Value("${common.secondary.db.name}")
private String dbName;
@Value("${COMMON_SECONDARY_SPRING_DATA_MONGODB_URI}")
private String mongoDBURI;
public String getMongoDBURI() {
return mongoDBURI;
}
public void setMongoDBURI(String mongoDBURI) {
this.mongoDBURI = mongoDBURI;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
/**
* Below bean is created as we want to make our code transactional.
* @param dbFactory
* @return
*/
@Bean(name="secondaryTransactionManager")
MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
MongoTransactionManager transactionManager = new MongoTransactionManager(dbFactory);
transactionManager.setRollbackOnCommitFailure(true);
return new MongoTransactionManager(dbFactory);
}
@Bean(name="secondaryMongoClient")
public MongoClient secondaryMongoClient() {
ConnectionString connectionString = new ConnectionString(getMongoDBURI());
MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.build();
return MongoClients.create(mongoClientSettings);
}
@Bean(name="secondaryMongoTemplate")
public MongoTemplate secondaryMongoTemplate() {
return new MongoTemplate(secondaryMongoClient(), getDbName());
}
}
Below is my sample code snippet of method annoted with @Transactional
@Override
@Transactional(transactionManager = "primaryTransactionManager",rollbackFor = {Exception.class})
public String addNewRecipe() throws Exception{
RecipesDAO recipesDao = new RecipesDAO();
recipesDao.setResourceId(UUID.randomUUID().toString());
recipeRepository.save(recipesDao);
throw new Exception();
// return "dummy";
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是我必须使用的代码片段,以便在代码执行流程中发生异常时回滚事务
在检查了我的类 MongoConfig.java 中使用的类的每个方法后,我得到了解决方案。下面 无论何时创建新的或修改 mongodb 文档的代码都存在,例如用于立即创建或修改文档的 somerepository.save(s) 代码,但通过添加primaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS); 和 secondaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS);
代码等待完整的执行流程,并检查该执行流程中是否发生异常。只有在检查执行流程中没有发生异常后,它才会创建或修改文档。
I got solution after checking each and every method of classes used in my class MongoConfig.java.Below is the snippet of code which i had to use in order to rollback transactions when exceptions occured in code execution flow
Earlier wherever code of creating new or modifying mongodb docs was there like say somerepository.save(s) code used to create or modify documents immedialtely but by adding primaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS); and secondaryMongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS);
code waits for complete execution flow and checks if any exception occured in this execution flow.It creates or modifies documents only after checking no exception occured in execution flow.