search

Home  >  Q&A  >  body text

java - 保存日志到mongo失败,乐观锁异常

想把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()后就可以正常保存了,想不明白为什么,希望大家帮忙解答一下,谢谢!

黄舟黄舟2807 days ago1146

reply all(1)I'll reply

  • 巴扎黑

    巴扎黑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!

    reply
    0
  • Cancelreply