spring-data-mongodb - 事务回滚在 Spring Data MongoDB 中不起作用
问题描述
我正在使用Spring Data MongoDB(2.2.5)和MongoDB 4.2.5 Community Version测试事务回滚功能。正如 Spring Data 官方文档中提到的,我在配置类中配置了 MongoTransactionManager,并在后端创建了一个包含 3 个成员的副本集。
此外,已将存储库用于 mongo db 事务。使用 @Transactional 注释了我的 Dao 方法。即使我已经在方法中实现了事务范围,我的数据仍然保存在集合(个人以及地址)中,并且在应用程序中的运行时异常上,Databse 层没有发生回滚。我已经从我的应用程序中提供了所需的源代码和跟踪。请帮助解决真实问题,如果我错过任何事情,请让我。
@Slf4j
@Configuration
@EnableMongoRepositories
@EnableTransactionManagement(proxyTargetClass=true)
class ApplicationConfig extends AbstractMongoClientConfiguration {
@Bean
MongoTransactionManager transactionManager(MongoDbFactory dbFactory) {
log.info("Creating dbFactory {}", dbFactory);
MongoTransactionManager manager=new MongoTransactionManager(dbFactory);
log.info("Creating manager {}",manager);
return manager;
}
@Override
public MongoClient mongoClient() {
return MongoClients.create("mongodb://localhost:27020,localhost:27021,localhost:27022/?replicaSet=rs0");
}
@Override
protected String getDatabaseName() {
return "testDB";
}
public @Bean MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoClient(), "testDB");
}
}
@Slf4j
@Service("TestDao")
public class TestDaoImpl implements TestDao{
@Autowired
PersonRepository repository;
@Autowired
MongoOperations ops;
@Autowired
AddressRepository addressRepo;
@Transactional
public void save(List<PersonVO> personList) {
//if(!p.getNationaliy().equalsIgnoreCase("AU"))
AddressVO addVo=new AddressVO();
addVo.setCity("COCHIN");
addVo.setCountry("IN");
addVo.setHouseNo("Rose Villa 123");
Address addr=AddressMapper.INSTANCE.ToAddress(addVo);
addressRepo.save(addr);
//ops.insert(addr);
log.info("Saving....");
for(PersonVO vo:personList) {
log.info("Saving person");
Person p=PersonMapper.INSTANCE.ToPerson(vo);
repository.save(p);
}
throw new RuntimeException();
}
}
这是日志、异常和堆栈跟踪。
2020-04-01 01:21:24.106 INFO 7696 --- [nio-7092-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-04-01 01:21:24.106 INFO 7696 --- [nio-7092-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-04-01 01:21:24.127 INFO 7696 --- [nio-7092-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 21 ms
2020-04-01 01:21:24.189 DEBUG 7696 --- [nio-7092-exec-2] o.s.d.mongodb.MongoTransactionManager : Creating new transaction with name [com.example.mongo.demo.service.TestServiceImpl.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2020-04-01 01:21:24.227 DEBUG 7696 --- [nio-7092-exec-2] o.s.d.mongodb.MongoTransactionManager : About to start transaction for session [ClientSessionImpl@3e82b37d id = {"id": {"$binary": "zw5ZFyfdRPSSOgZ/pW/D3A==", "$type": "04"}}, causallyConsistent = true, txActive = false, txNumber = 0, error = d != java.lang.Boolean].
2020-04-01 01:21:24.228 DEBUG 7696 --- [nio-7092-exec-2] o.s.d.mongodb.MongoTransactionManager : Started transaction for session [ClientSessionImpl@3e82b37d id = {"id": {"$binary": "zw5ZFyfdRPSSOgZ/pW/D3A==", "$type": "04"}}, causallyConsistent = true, txActive = true, txNumber = 1, error = d != java.lang.Boolean].
2020-04-01 01:21:24.238 INFO 7696 --- [nio-7092-exec-2] c.e.mongo.demo.service.TestServiceImpl : Saving
2020-04-01 01:21:24.239 DEBUG 7696 --- [nio-7092-exec-2] o.s.d.mongodb.MongoTransactionManager : Participating in existing transaction
2020-04-01 01:21:24.285 DEBUG 7696 --- [nio-7092-exec-2] o.s.data.mongodb.core.MongoTemplate : Inserting Document containing fields: [houseNo, city, country, _class] in collection: address
2020-04-01 01:21:24.334 INFO 7696 --- [nio-7092-exec-2] org.mongodb.driver.connection : Opened connection [connectionId{localValue:7, serverValue:37}] to localhost:27021
2020-04-01 01:21:24.501 INFO 7696 --- [nio-7092-exec-2] com.example.mongo.demo.dao.TestDaoImpl : Saving....
2020-04-01 01:21:24.501 INFO 7696 --- [nio-7092-exec-2] com.example.mongo.demo.dao.TestDaoImpl : Saving person
2020-04-01 01:21:24.530 DEBUG 7696 --- [nio-7092-exec-2] o.s.data.mongodb.core.MongoTemplate : Inserting Document containing fields: [name, age, gender, nationaliy, _class] in collection: person
2020-04-01 01:21:24.532 INFO 7696 --- [nio-7092-exec-2] com.example.mongo.demo.dao.TestDaoImpl : Saving person
2020-04-01 01:21:24.533 DEBUG 7696 --- [nio-7092-exec-2] o.s.data.mongodb.core.MongoTemplate : Inserting Document containing fields: [name, age, gender, nationaliy, _class] in collection: person
2020-04-01 01:21:24.536 DEBUG 7696 --- [nio-7092-exec-2] o.s.d.mongodb.MongoTransactionManager : Participating transaction failed - marking existing transaction as rollback-only
2020-04-01 01:21:24.536 DEBUG 7696 --- [nio-7092-exec-2] o.s.d.mongodb.MongoTransactionManager : Initiating transaction rollback
2020-04-01 01:21:24.537 DEBUG 7696 --- [nio-7092-exec-2] o.s.d.mongodb.MongoTransactionManager : About to abort transaction for session [ClientSessionImpl@3e82b37d id = {"id": {"$binary": "zw5ZFyfdRPSSOgZ/pW/D3A==", "$type": "04"}}, causallyConsistent = true, txActive = true, txNumber = 1, error = d != java.lang.Boolean].
2020-04-01 01:21:24.538 DEBUG 7696 --- [nio-7092-exec-2] o.s.d.mongodb.MongoTransactionManager : About to release Session [ClientSessionImpl@3e82b37d id = {"id": {"$binary": "zw5ZFyfdRPSSOgZ/pW/D3A==", "$type": "04"}}, causallyConsistent = true, txActive = false, txNumber = 1, error = d != java.lang.Boolean] after transaction.
2020-04-01 01:21:24.554 ERROR 7696 --- [nio-7092-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException] with root cause
java.lang.RuntimeException: null
at com.example.mongo.demo.dao.TestDaoImpl.save(TestDaoImpl.java:57) ~[classes/:na]
at com.example.mongo.demo.dao.TestDaoImpl$$FastClassBySpringCGLIB$$8c1970a4.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366) ~[spring-tx-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99) ~[spring-tx-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at com.example.mongo.demo.dao.TestDaoImpl$$EnhancerBySpringCGLIB$$8ea2a8.save(<generated>) ~[classes/:na]
at com.example.mongo.demo.service.TestServiceImpl.save(TestServiceImpl.java:46) ~[classes/:na]
at com.example.mongo.demo.service.TestServiceImpl$$FastClassBySpringCGLIB$$949c2e6a.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366) ~[spring-tx-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99) ~[spring-tx-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at com.example.mongo.demo.service.TestServiceImpl$$EnhancerBySpringCGLIB$$7980a7ba.save(<generated>) ~[classes/:na]
at com.example.mongo.demo.controller.TestController.savePersons(TestController.java:33) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:109) ~[spring-boot-actuator-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1639) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
解决方案
推荐阅读
- pine-script - 为今天和昨天扩展框
- spring-boot - Spring Boot 管理员兼容性 Spring Boot 版本和日志记录实例
- spring - 如果抛出运行时异常,然后在用spring的@Transactional注解的方法中捕获,导致事务回滚?
- css - 如何配置 webpack 或 nextjs 以从材料自定义样式创建 css 文件,然后将其注入 header
- c - 在特定的“i”索引之后将二维数组传递给函数,因此只需从二维数组传递特定的一个 d
- reactjs - 在样式组件中正确键入(TS)主题并使用对象语法
- javascript - 启动 .splice 功能后项目不会被删除
- java - 更新 Kafka sink mongo 上的部分字段
- routes - 使用 GPS 坐标进行路线匹配(跟踪不连续)
- javascript - 设计 Recoil.js 原子以将对象数组显示到表格中