最近在开发过程中遇到过一个问题。
- 前情提要: 通话过程中的数据称之为事中数据,通话完成后的数据是事后数据。
- 问题描述 接收到事中数据会将数据插入表,接收事后的数据会判断该数据存不存在,如果存在则更新,如果不存在则插入,作为一个兜底,处理完事后数据会将该数据的状态由事中改为事后,但是最后发现这条数据通话结束后一直是事中的状态。
- 分析: 看到数据的状态没更新,我想到的肯定是事后的数据没有进行更新,一般来说肯定是数据在事中的时候就插入了,先后顺序很明显,了解到一个信息是当这个页面打开的时候才会接收到事中的数据,因此我猜测的执行顺序应该是先挂断了电话,事后数据会进行消费,这时候判断数据库里面的数据不存在,正准备走兜底逻辑插入数据库,就在这时候点开了页面导致事中的数据也会接收到,事中的数据先插入了,然后事后这边插入失败了,所以最后数据库里面的数据一直是事中的。
- 解决: 由于之前使用的插入语句是ignore,所以插入的时候并没有报错,导致日志也没发现异常,去掉了ignore,对于这个报错进行捕获,然后为了解决这个并发问题,使用了 AtomicInteger并发类来控制我重试的次数,一般来说,第二次应该就会走更新的逻辑了。 后面了解到oracle数据库里面好像有MERGE语句可以实现,但是由于业务上的问题,有的字段状态会有变化,因此不能采用。
- 最后 这是我的处理方式,如果大家有更好的方式,欢迎讨论。