这是群友公司的一个问题
模拟环境如下
-
drop table if exists t1;
-
drop table if exists t2;
-
create table t1 (
-
id int not null primary key ,
-
batchid int ,
-
state int
-
);
-
-
create table t2(
-
batchid int not null primary key,
-
state int
-
);
-
-
insert into t1 values(1,1,0);
-
insert into t1 values(2,1,0);
-
-
insert into t2 values(1,0);
-
-
drop procedure if exists pmax;
-
drop procedure if exists pmin;
-
-
DELIMITER $$
-
create procedure pmax ()
-
begin
-
declare v_id int;
-
declare v_size int;
-
select max(id) into v_id from t1 where batchid =1;
-
-
update t1 set state=1 where id=v_id;
-
select count(*) into v_size from t1 where state=0 and batchid=1;
-
if v_size=0 then
-
update t2 set state=1 where batchid=1;
-
select * from t2;
-
end if ;
-
end $$
-
-
-
create procedure pmin ()
-
begin
-
declare v_id int;
-
declare v_size int;
-
select min(id) into v_id from t1 where batchid =1;
-
-
update t1 set state=1 where id=v_id;
-
select count(*) into v_size from t1 where state=0 and batchid=1;
-
if v_size=0 then
-
update t2 set state=1 where batchid=1;
-
select * from t2;
-
end if ;
-
end $$
-
-
DELIMITER ;
环境:
MySQL 5.6.14 innodb
可重复读隔离级别
业务逻辑:
其中t1表是一个任务表,每个任务有一个id
每一个批次(batchid)可能有多个任务.
如果t1表某个批次所有的任务都完成了,则修改t2表该批次的状态为完成
模拟批次 1 有两个任务 id分别为 1和 2
pmax过程处理 id 为2 的任务, pmin处理id为1 的任务
预期两个过程执行完成,t2 表的状态可以修改为 1, 但是 最终t2表的状态始终都是 0 ,没有得到任何的修改.
这是因为事务隔离,屏蔽了其他线程操作的结果

如果没有加锁读,则不能达到预期的结果.
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29254281/viewspace-2142257/
,如需转载,请注明出处,否则将追究法律责任。