mysql 高并发下的数据同步问题

发布于 2022-09-11 14:48:27 字数 747 浏览 43 评论 0

目前,遇到这样一个使用 mysql 的问题,先描述下场景(为了方便答题,已经做了部分简化):

现在有两台机器,使用同一个数据库账户,同时访问操作一个 mysql 地址,它们都会有如下的操作:

  • 根据 id 查询一条数据。
  • 在原有的数据基础上做增量式改动。
  • 将变动好的数据根据 id 进行更新。

所以,有时候会有这样的一个情况出现:

  • 机器一根据某 id 查询得到数据。
  • 机器二根据某 id 查询得到数据。
  • 机器一在原有的数据基础上做增量式改动。
  • 机器二在原有的数据基础上做增量式改动。
  • 机器一请求 mysql 存储数据。
  • 机器二请求 mysql 存储数据。

这个时候,机器一存储的数据的更新痕迹就被完全抹掉了。这里的这个过程,实际上应该“变成“串行化的,也就是说,两个增量式改动我都想保留。

尝试使用 mysql 的事务来解决这个问题,采用了串行化的隔离级别,但是我发现貌似没能解决,事务可以保证在某些语句出错的时候无额外影响,但是这里本来也没有错误。

当然,我对事务的了解并不深刻,也许用的不是很对。

这里还有一点,增量式改动比较耗时,并且需要数据依赖和额外计算,不能简单地通过 update 语句完成。

我用的是 nodejs 和 sequelize,暂时还没有找到解决方案。

大家如果有什么经验或者建议,希望能指教一二,不胜感激~

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

坏尐絯 2022-09-18 14:48:27

这其实就是一个事务的脏读取问题。解决办法有两种:

1,事务开始
查询 (查询一个能作为未被其他事务更新的依凭,例如最后更新时间)
更新->更新的时候加上where并且update该数据的最后更新时间,例如where last_update_time(最后更新时间) = 该事务刚开始时查出来的那个时间。
commit提交。
解析下这种方法,其实就是利用update的where条件不受脏读取的影响,若该数据中途被其他事务更新过了,则update失败,回滚。
结果:事务a运行成功,事务b因为update条件不成立,回滚了。

2,使用select .... for update 进行锁表。
结果:事务b会等到事务a提交之后再运行。

个人建议,方法一和方法二都能够解决并发请求时脏读取的问题,最好是两种方法合并使用。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文