Mysql 当多个程序写入同一数据库时,如何避免无效数据?
鉴于下表:Mysql 当多个程序写入同一数据库时,如何避免无效数据?,mysql,Mysql,鉴于下表: CREATE TABLE `MCVESchema`.`MCVETable` ( `PrimaryKeyColumn` INT NOT NULL AUTO_INCREMENT, `Increment` INT NULL DEFAULT 0, PRIMARY KEY (`PrimaryKeyColumn`)); 如果多个程序将访问同一行以更改Increment列中的值,则需要考虑以下问题: 程序实例A访问第0行的Increment字段和 将值从0增加到1 程序访问的实例B
CREATE TABLE `MCVESchema`.`MCVETable` (
`PrimaryKeyColumn` INT NOT NULL AUTO_INCREMENT,
`Increment` INT NULL DEFAULT 0,
PRIMARY KEY (`PrimaryKeyColumn`));
如果多个程序将访问同一行以更改Increment
列中的值,则需要考虑以下问题:
- 程序实例A访问第0行的
字段和 将值从0增加到1Increment
- 程序访问的实例B
第0行的字段,并将值从0增加到1Increment
- 实例
一组程序写入数据库-
字段为 现在1(这是预期的行为)第0行的增量
- 程序的实例B写回
数据库-
第0行的字段仍然是1(应该是2)Increment
A: SELECT -> increment
B: SELECT -> increment
A: 0 -> increment
B: 0 -> increment
A: increment += 1
B: increment += 1
A: UPDATE increment = 1
B: UPDATE increment = 1
由于交错,它不是以2结尾,而是以1结尾
实现这一点的更好方法是作为原子操作,如在瞬间发生的操作,不依赖于正确应用之前或后续步骤
这通常显示为:
UPDATE counter_table SET increment=increment+1 WHERE id=?
这些语句中的每一条都将按顺序从开始到结束独立运行,并且不会出现排序错误。每次增量将调整+1
这在进行银行类业务时尤为重要
从技术角度讲,您可能正在创建一个计数器表,或者一个具有类似表的序列生成器,因此,请通过搜索这些特定事物的示例来研究您有哪些实现模式。而tadman的可能是最好的,如果您碰巧在一个原子SQL操作中无法达到目标,并且仍然担心竞争条件,那么另一种选择是使用MySQL的锁定功能 是的,如果多个进程/服务器/web请求都尝试读取然后更新同一行,那么您就有问题了。一些可能的修复方法包括通过单个处理程序、事务、锁表序列化更新,让其他人退出,等待一段随机间隔,然后重试。现在我真的很傻,因为我自己没有想到这一点。