请教大家: 如何解决数据库并发操作导致的数据不一致问题?(mysql)

2016-04-07 09:59:55 +08:00
 palmers

情形如下:

  1. A 、 B 同时读取到信息 张三 20 男
  2. 这时 A 在页面修改 张三 25 男 保存
  3. 然后 B 修改信息 张三 20 女 保存

如此, A 的信息被覆盖了

谢谢大家啦!

5324 次点击
所在节点    程序员
26 条回复
iMouseWu
2016-04-07 10:15:28 +08:00
乐观锁可以解决吧
amlun
2016-04-07 10:18:01 +08:00
没有看出数据不一致。。
如果是防止同时更改,可以对该条数据加锁啊
shoaly
2016-04-07 10:19:48 +08:00
这个不是锁能够搞定的, 而是程序逻辑的问题.
A 改动的是 年龄
B 改动的是性别
两个操作本身不冲突的, 现在冲突是因为 代码修改的是全部...

解决办法
只保存 要修改的那一个字段, 不要都修改.
hp3325
2016-04-07 10:20:12 +08:00
你可以加个时间戳, A 保存时更新时间戳, B 保存时获取时间戳,对比是否更新过,如果更新过,提示用户。
甚至可以用存储过程,让数据库自动保证数据一致。
UnisandK
2016-04-07 10:21:17 +08:00
3L+1
qiyuey
2016-04-07 10:23:16 +08:00
这确实是程序的问题
Jaylee
2016-04-07 10:24:02 +08:00
你知道锁吗?
shiny
2016-04-07 10:25:36 +08:00
SELECT FOR UPDATE
shiny
2016-04-07 10:27:00 +08:00
保存前检查数据是否为修改前的数据
Infernalzero
2016-04-07 10:39:44 +08:00
LZ 的问题不在于加不加锁,关键是都用了全量更新
所以为了避免这种情况都是只更新修改的字段,非空字段不更新
不要拿查询出来的对象去更新,而是 new 一个新的对象仅把之前查询出来的对象的主键 set 进去
yangdehua
2016-04-07 10:56:00 +08:00
事务隔离级别设置为, serializable
连读都加锁,你说好不好啊
loading
2016-04-07 11:03:05 +08:00
锁解决不了。

前台只提交更改的就行。

如果可以,考虑下 websock 实时更新并提醒。
amlun
2016-04-07 11:06:56 +08:00
@shoaly
感觉问题被你带偏了。。。
其实题主都没有说真实场景,万一张三的信息确实如 B 的更改呢?
amlun
2016-04-07 11:08:32 +08:00
所以题主---表达清楚需求啊!
gamexg
2016-04-07 11:17:06 +08:00
楼主的这个场景涉及前台,无法直接锁行,同意 @hp3325 的观点,使用乐观锁,增加时间戳,保存时比较,冲突了提示用户手工修正。

其他的并发能使用事务+悲观锁就直接锁行,简单方便快捷。
likuku
2016-04-07 11:24:02 +08:00
性别如今也不是不能改的...要政治正确啊。参考 FaceBook
Numbcoder
2016-04-07 11:25:06 +08:00
用 etag
A , B 在读取信息时,保存信息的 etag ,
然后在发送更新请求时带上 etag ,执行数据库更新操作前检查 etag 是否变化,如果 etag 一致,保存更新,否则更新失败
jugelizi
2016-04-07 11:49:43 +08:00
这还叫并发 。。
难道修改不应该保存修改记录吗?
redis 好像有原子操作更新数据前检测数据有没有变化过
yxzblue
2016-04-07 11:57:01 +08:00
难道不是 1L 说的乐观锁就解决了么 ...
yanyuan2046
2016-04-07 12:12:30 +08:00
SELECT FOR UPDATE +1

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/269151

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX