非并发原因引起的乐观锁异常故障分析

新项目上线后,发现经常会报乐观锁错

org.springframework.orm.jpa.JpaOptimisticLockingFailureException: Optimistic locking errors were detected when flushing to the data store.  The following objects may have been concurrently modified in another transaction: [entity.Counter-entity.Counter-57218]; nested exception is <openjpa-1.1.0-r422266:657916 nonfatal store error> org.apache.openjpa.persistence.OptimisticLockException: Optimistic locking errors were detected when flushing to the data store.  The following objects may have been concurrently modified in another transaction: [entity.Counter-entity.Counter-57218]

 

这是一个典型的乐观锁错,自然想到代码中是否存在并发写入问题

 

检查代码后没找到可疑代码,而且看报错的实体Counter一般情况下也不会存在并发

 

分析了下报错的数据和报错时间,发现基本都是0点之后开始(定时任务主要集中在0点),重启后故障解除; 而且负责执行定时任务的那台机器报错情况少于另一台机器,但是也有报错

 

检查了所有定时任务,也没发现问题

 

但是问题性质基本上可以认定:有实体被更新后,jpa的datecache没有更新;可能和群集有关.

 

首先根据报错的实体类型(Counter,UserStat)分别检查

 

查了最近2天的UserStat类报错的数据,都是该用户有过收藏操作的,而正好有个定时任务是重置收藏数据的,所以就很自然联想到是否是该定时任务的的更新没有同步群集

 

更新语句用到jpa的批量更新api: Query.executeUpdate();

 

在线上2台应用服务器上做了简单测试后确认了猜想: 目前用到的jpa群集实现不支持批量更新操作- -! 没办法,暂时只能将更新语句改成传统的List查询后逐个merge()

 

这个问题解决后,第二天发现线上还是有很多异常,侥幸心理+失望...

 

实在想不出其他原因,只好开始查该异常出现的时间点, 发现是从2周前切换新服务器后开始的, 问系统组同事要了切换前的服务器日志,发现没有这个问题,那就奇怪了,服务器切换并没有改动程序,那问题原因估计也和程序无关!

 

不经意间,发现旧服务器日志里有大量群集同步异常

[07-17 00:02:39.469] 2010-07-17 00:02:39,468 ERROR [openjpa.Runtime] 100 - 发出消息出错!
[07-17 00:02:39.469] java.lang.NullPointerException
[07-17 00:02:39.469]  at openjpa.event.MulticastRemoteCommitProvider$SendThread.run(MulticastRemoteCommitProvider.java:152)
[07-17 00:02:39.469]  at java.lang.Thread.run(Thread.java:619)

 

恍然大悟!!服务器切换后,旧的应用没有停掉,仍旧在跑,并且每天0点会执行定时任务,导致新应用的jpa缓存和数据库不同步,造成大量乐观锁错!

 

停掉旧应用,问题解决~

 


 

总结:

这起故障的原因:1,群集实现不支持的更新操作; 2,未在群集中的应用更新数据导致不同步; 两个不同的原因导致jpa的数据缓存和数据库中的不一样,从而引发乐观锁异常

在处理故障时,思维还是太狭窄,效率不高(前前后后一共花了3天)

明明能肯定是jpa缓存过期导致的,但是由于找不到可能造成过期的代码和原因,所以不敢确定.

 

福尔摩斯有过一句话:

当所有的不可能都排除时,剩下的,就算再不可能,也是真相。

--When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth

 

借用此话聊以自慰:)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值