【发布时间】:2018-12-11 06:50:38
【问题描述】:
目标
当用户发出请求(REST API)时,我想将 N 记录从表 source 复制到表 destination。
当前解决方案
- 开始事务。
- 截断表
destination。 - 插入表
destinationselect fromsourceLIMITN(单个查询)。 - 提交事务。
问题
N 可以介于100000 - 2500000 之间,如果用户使用N 记录一个接一个地发出两个请求,则将插入2xN 记录。
示例流程:
- [Action - 1] 用户请求复制
100记录。 - [Action - 1] 交易开始。
- [Action - 2] 用户请求复制
200记录。 - [Action - 1] 截断表
destination。 - [Action - 2] 交易开始。
- [Action - 2] 截断表
destination。 - [操作 - 1] 插入查询已触发。(复制
100记录) - [操作 - 2] 插入查询已触发。(复制
200记录) - [Action - 1] 交易结束。
- [Action - 2] 交易结束。
结果:destination 表中有300 记录。
所需的解决方案
我想确保在任何给定时间点只发生一次插入。
- 开始交易。
- 锁定
destination表。 - 截断
destination表。 - 插入
destination表。 - 解锁
destination表。 - 结束交易。
请注意,当我只想写入锁定目标表时,不应发生 写入 操作(但仍应发生读取操作)。
其他详情
- MySQL(数据库)
- NodeJS(REST API 服务器)
- 没有存储过程
临时解决方案
暂时我们依赖于在开始事务之前在数据库中设置的标志,然后在事务完成后取消设置。设置标志时到达的任何其他请求都将终止并显示一条消息(进程已在运行,请稍后再试)
请帮助我找到更好的解决方案。如果您需要更多详细信息,请告诉我。
谢谢
【问题讨论】:
-
MySQL 可以挂起请求并在表被锁定时一一执行。如果你害怕超时。只需将
connect_timeout设置为您想要的足够长的时间。 -
也许更好地解释您要解决的问题,而不是您想如何解决它,这会带来一些更好的方法,这个方法很糟糕。在我看来XYProblem
-
@JorgeCampos 是的,我已经提到了我的问题。我不希望 2 次插入同时发生。
-
@MatrixTai 您能否详细说明或指出一些参考资料?
-
mysqltutorial.org/mysql-table-locking,看看,你可以一个一个的执行请求。