最近做了一个区块链数据相关的项目,业务系统需要跟区块链上数据同步,在测试环境没有任何问题,部署到成员方之后突然出现数据同步失败。仔细分析了业务代码没有发现任何异常,对比了各种环境之后,发现只有数据库事务隔离级别不同,怀疑是隔离级别导致。
整个数据同步流程的事务情况为
1.对每个块开启一个外层事务。
2.循环对块中的每笔交易使用require_new开启一个内层事务。
3.提交内层事物。
4.提交外层事务。
由于每笔交易的处理需要校验起始金额,而起始金额需要依赖前一笔交易的处理结果。
事务的隔离级别为rc时外层事务可以读到内层提交的事务结果,当为rr时外层事务无法读到内层事务提交的结果。
基于以上两点,我们可以得出
在数据库隔离级别为rc时,不会有任何问题。
在数据库隔离级别为rr时,如果一个块中只有一笔交易也不会有问题。
在数据库隔离级别为rr时,如果一个块中有多笔交易就会有问题。原因是处理完块中第一笔交易之后再处理第二笔时,第一笔交易的处理结果虽然已经提交但是外层事务不可见,所以在处理第二笔时校验起始金额出错,然后整个外层事务会回滚,重新处理第一笔交易。但是由于第一笔交易已经提交到数据库,所以依然处理失败。
在事务有嵌套的时候一定要注意事务隔离级带来的影响。