mysql并发问题, select 50条记录,然后再update这50记录,标记这50条记录状态为已获取

MySql 码拜 8年前 (2016-02-19) 1092次浏览
伪代码如下:

begin transaction
select * from table where state=0 limit 1, 50
update table set state=1, getuser=5 where id in (上面50条记录的id号)
comit transaction

在并发的情况下,要保证每个用户的逻辑都是正确的,上面的事务可行吗?
需求就是:获取50条未读取的记录(state=0),然后取完了并更新state=1,getuser=5(指哪个用户获取了),而这个表是全部用户都需要获取的,
就像是这个表保存了未完成的任务,等大家来获取这些任务。

解决方案

10

update table set state=1, getuser=5 where state=0 limit 50;

10

写出一个语句:

begin transaction
 
update table set state=1, getuser=5 where state=0  limit 1, 50
 
commit transaction

30

主要是想实现,用户取到50条,就只更新这50条记录,并且这个用户在客户端看到的也是这50条记录。
用户B怎么办? 在用户B去更新的时候,当前用户B取到的纪录,实际上,已经被用户A修改了,你是要更新还是不再更新?
假如用户A修改了,B就不用再去修改了, 也不能改别的纪录, 那你这么写是可以的。
原因是 AND state=0 条件的限制, 实际上 state 纪录值已经被A改成 1 了。
假如A修改后, B还需要对之前取到的数据进行修改, 那就不能添加   AND state=0  这部分。
更新都会给纪录加锁的, 不需要考虑单纯的 update 语句在并发时能否会冲突的问题了。
并发插入时,原则上数据表有一个读锁时,其它进程无法对此表进行更新操作,但在一定条件下,MyISAM表也支持查询和插入操作的并发进行。
MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别可以为0、1或2。
a、当concurrent_insert设置为0时,不允许并发插入。
b、当concurrent_insert设置为1时,假如MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录。这也是MySQL的默认设置。
c、当concurrent_insert设置为2时,无论MyISAM表中有没有空洞,都允许在表尾并发插入记录

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明mysql并发问题, select 50条记录,然后再update这50记录,标记这50条记录状态为已获取
喜欢 (0)
[1034331897@qq.com]
分享 (0)