想把mongo保存进mongoDB中,使用的spring-boot-data-mongo.
在dao层可以正常保存,但是写在service中报错:
org.springframework.dao.OptimisticLockingFailureException: Optimistic lock exception on saving entity: {_class=com.zihexin.base.mongo.MerchantRequestLog, version=1, requestIp=1111, requestDate=Tue Mar 21 17:15:01 CST 2017, requestParam=22222, paymentWay=213} to collection merchant_request_log
at org.springframework.data.mongodb.core.MongoTemplate$12.doInCollection(MongoTemplate.java:1135)
at org.springframework.data.mongodb.core.MongoTemplate$12.doInCollection(MongoTemplate.java:1108)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:461)
at org.springframework.data.mongodb.core.MongoTemplate.doUpdate(MongoTemplate.java:1108)
at org.springframework.data.mongodb.core.MongoTemplate.doSaveVersioned(MongoTemplate.java:977)
at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:941)
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.save(SimpleMongoRepository.java:78)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:483)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:468)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:440)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy84.save(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy84.save(Unknown Source)
at com.zihexin.base.service.MongoService.saveRequestLog(MongoService.java:44)
at com.zihexin.ZhxpayCommonApplicationTests.test4(ZhxpayCommonApplicationTests.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
service中代码:
@Service
public class MongoService {
private static Logger logger = LoggerFactory.getLogger(MongoService.class);
/**商户请求相关*/
//判断流水号重复或者为空
@Autowired
MerchantRequestLogRepo merchantRequestLogRepo;
public boolean exists(String requestId){
return merchantRequestLogRepo.exists(requestId);
}
//异步保存mongo日志
// @Async
public void saveRequestLog(String ip,String paramMap, String requestId,String paymentWay){
long start = System.currentTimeMillis();
logger.info("Async Save Merchant Request Log Begin : ");
MerchantRequestLog merchantRequestLog = new MerchantRequestLog();
merchantRequestLog.setRequestDate(new Date());
merchantRequestLog.setRequestId(requestId);
merchantRequestLog.setRequestParam(paramMap);
merchantRequestLog.setRequestIp(ip);
merchantRequestLog.setPaymentWay(paymentWay);
// merchantRequestLog.setHostIp(Constants.hostAddress);
merchantRequestLogRepo.save(merchantRequestLog);
logger.info("Async Save Merchant Request Log End ,Spend Time :{} ms",System.currentTimeMillis()-start);
}
save()方法为继承MongoRepository中的方法,我改为insert()后就可以正常保存了,想不明白为什么,希望大家帮忙解答一下,谢谢!
巴扎黑2017-04-18 10:53:27
2 points for consideration:
1. Optimistic locking mainly relies on version to handle conflicts. The exceptions of optimistic locking are mainly:
1)Insert的时候发现待插入的数据,有更为新的version的数据了,因为有其他的同样的Insert的操作;
2)Update的时候发现待修改的数据,有更为新的version的数据了,因为有其他的同样的Update的操作。
这个需要检查一下应用需求,是否可以接受这种异常;如果接受不了,就需要进一步修改。
2. Why doesn’t Save work, but Insert does? Please note the difference between Save and Insert in MongoDB.
1)Save如果带_id,有可能是Update;
2)Save如果不带_id,和Insert一样。
简而言之,Save可以是一个Update操作。
For reference.
Love MongoDB! Have Fun!