事务一致性测试

简介: 事务一致性测试


很多知识细节都来自生产事故,只有经历过,才能记得住。今天的故事,也源于一次线上事故。


01


某天,做完产品的业务升级后,还是比较放松的。刚想搞点别的事,用户群就有用户反馈有问题。真的是不让人省心,先看问题吧。如下图,用户在添加卡片时,提示错误,无法新增,但是列表里又多出了一些数据。点击查看详情时,又提示空白。


 

这个问题还是比较严重的,优先解决报错的问题,回想了升级的内容后,很容易就定位到问题了,顺利解决(你以为我要说报错的问题吗?这是另一个更长的故事)。

 

解决完问题后,我关注的是另一个问题:按理说,如果新增数据报错了,列表数据应该也是没有的,这里第2步中会多出这么几条数据?


02


根据对系统的了解,我判断出列表数据读取的是ES上的数据,而详情页(第3步)中的数据来源于数据库,是因为两边的数据不一致吗?查了下数据库,确实没有那几条重复的数据。那问题就比较明显了,应该是新建卡片时,同进写ES和数据库,出了问题,导致两边数据不一致。拉代码看看呗。

如上图,在新增卡片时,先做了数据库的插入,然后做ES的插入,最后做事件的通知及其他操作。看着好像也没什么问题。

 

等等,不对,为什么这里没做事务管理?如果有事务,失败了不就会回滚么?


03


研发应该不会犯这么低级的错误,再看看代码。想到了Spring中有统一的事务管理注解,应该会使用到的,为什么会没生效呢?找了下,还真是有用了Transactional,那应该不会有问题的呀。


 

正常情况下,只要在类上添加@Transactional注解就完事了,那是什么原因导致注解失效了呢?问问ChatGPT吧,回复如下:



看着也没什么问题,这些情况都不符合我的场景。那问题出在哪里呢?在其官网上也没找到相关的信息,看看其他大神的文章吧。在Bing上搜索了一阵子,发现在别人的文章中有提到@Transactional失效中的原因有一条:如果数据库引擎不支持事务,那么就无法回滚对应的数据。

 

隐约记得ES是不支持事务的,会是这个问题么?

 

04


继续问问ChatGPT吧,看看它能给我什么思路。

看来问题的根源找到了:


用户在操作新增卡片时,先往数据库插了条数据,然后ES上也增加了对应的数据,但是在做事件更新时,出了问题(第1步的报错信息来源于此),触发了@Transactional事务回滚的机制,所以数据库里的数据被回滚了。但是由于ES不支持事务,所以@Transactional也没办法回滚,所以列表中的数据还是能被查看到(第2步,ES中的数据还是在的),但是点击详情(第3步)时,因为在数据库中找不到对应的数据,所以页面无法显示。

 

05


针对这个问题,团队讨论了下,解决方案有三种:


1. 因为双写(同时写数据库和ES),才导致了这个问题,那就去掉双写,只写数据库,然后通过异步或者MQ的方式,再去写ES,这样能解决一致性的问题,但是时效性会差点。


2. 在异常类中统一处理,如果发现这个方法有异常抛出,就记录数据信息,去ES中做对应的回退操作(分类处理,例如数据库是insert操作,就调用ES的delete操作数据删除),人为实现ES的回滚;


3. 解偶,在方法中只处理双写操作,其他的业务逻辑做异步处理(例如这个场景中,事件更新可以异步处理,并做对应的补偿机制),这样就不会影响主数据的一致性。


最终我们选择了代价最小的第3种方案,如果你有更好的方案,可以联系我哟,感谢。

 


06


解决完问题,回想下如何避免此类事件的发生(应该是个小概率事件)。对于事务的一致性测试,在平时很容易被忽略,大家都还是相信开发会使用事务的。但是对于事务管理是否会失效,没有引起足够的重视。

 

对于测试人员而言,常见的事务一致性测试场景有哪些呢?


a. 双写或者多写的情况:随着现在中间件使用得越来越多,双写或者多写的情况也会增加,当数据记录在多个地方时,需要关注一致性问题


b. 异步处理,常见的是MQ,如果消费失败,是否有对应的补偿机制来保障一致性


c. 跨系统的数据存储,有些业务数据存在关联性,又分布在不同的系统中,如何保障一致性,也是测试人员需要关注的。

相关文章
|
1月前
|
运维 Prometheus 监控
如何在测试环境中保持操作系统、浏览器版本和服务器配置的稳定性和一致性?
如何在测试环境中保持操作系统、浏览器版本和服务器配置的稳定性和一致性?
|
2月前
|
分布式计算 Hadoop Unix
Hadoop-28 ZooKeeper集群 ZNode简介概念和测试 数据结构与监听机制 持久性节点 持久顺序节点 事务ID Watcher机制
Hadoop-28 ZooKeeper集群 ZNode简介概念和测试 数据结构与监听机制 持久性节点 持久顺序节点 事务ID Watcher机制
51 1
24Redis - 事务测试案例
24Redis - 事务测试案例
57 0
|
Java 测试技术 数据库连接
MyBatis基本用法 && 什么是自动化测试 && Spring事务和事务传播机制 && 性能测试概念和术语 && Loadrunner安装
MyBatis基本用法 && 什么是自动化测试 && Spring事务和事务传播机制 && 性能测试概念和术语 && Loadrunner安装
91 0
|
缓存 测试技术 数据库
软件测试面试题:假设在测试过程中某些事务的响应时间过长,但分析应用服务、数据库以及网络都属于正常现象,问题可能出现的原因有哪些?
软件测试面试题:假设在测试过程中某些事务的响应时间过长,但分析应用服务、数据库以及网络都属于正常现象,问题可能出现的原因有哪些?
376 0
|
Java 数据库连接 数据库
高效掌握JDBC技术(三)| 三层架构理念 | 书写符合事务特性的工具类 | JUnit测试框架 | JDBC项目开发步骤(下)
高效掌握JDBC技术(三)| 三层架构理念 | 书写符合事务特性的工具类 | JUnit测试框架 | JDBC项目开发步骤
110 1
|
Java 数据库连接 数据库
高效掌握JDBC技术(三)| 三层架构理念 | 书写符合事务特性的工具类 | JUnit测试框架 | JDBC项目开发步骤(上)
高效掌握JDBC技术(三)| 三层架构理念 | 书写符合事务特性的工具类 | JUnit测试框架 | JDBC项目开发步骤
146 1
|
机器学习/深度学习 算法 数据可视化
机器学习避坑指南:训练集/测试集分布一致性检查
机器学习避坑指南:训练集/测试集分布一致性检查
机器学习避坑指南:训练集/测试集分布一致性检查
|
Java 数据库 容器
声明式事务测试 :Spring注解笔记系列(一)
事务拦截器:先获取事务相关的一些属性,再来获取PlateformTransactionManager,如果事先没有添加任何指定TransactionManager,最终会从容器中按照类型获取一个PlateformTransactionManager
167 0
下一篇
DataWorks