实际项目开发中遇到这样的一个问题,主表的读取和副表的读取,前者为表更新之前的结果,后者为表更新之后的结果。由此怀疑mysql事务提交之后表更新不是按照表的语句前后顺序执行,而是按照mysql的自身的优化机制(并无实证)来决定语句先后的,但是事务未执行完毕之前对外部是不可见,要不就回出现脏读,所以上述即使成立,也不会造成该问题。
事情的缘由是这样:外部应用在提交业务数据的变更之前,会先调用api读取上述的两个表,进行一定的运算,然后调用另一个api写入主副表信息。由于并发处理不好,导致有几次的读写。按照业务逻辑主表和副表是一次事务操作写入,另外主表在前,副表在后。由于并发的原因,导致出现了一个奇怪的现象,在第二次的并发读写中,外部应用得到了这样的结果:主表为更新前的结果,副表为更新之后的结果,由此怀疑事务的表操作顺序,貌似事务先执行了副表,后执行了主表。
后续的分析确定了最终的原因如下:
外部api读写主副进行计算,在读取的时候上一次写操作还未完成,所以主表读取的数据为旧数据,之后写操作完成了之后,外部api读取至副表信息,所以读取到新的副表信息。其实外部api读取主副表只是一次(接口内部实现为先读取主信息,再读取副表),所以造成该异常。
总结:①事务依次执行的重要,最好锁机制(缓存或文本锁......)②做好数据写入的校验......