在做大型并发的业务的时候,mysql的锁对整个程序的正确运行和高效运行都有很重要的作用。这次研究的mysql的锁的机制,现将代码记录下参考(线程一的执行序号对应线程二的执行序号):
线程一的几个操作
-- 【1】
-- 加表级别的写锁
-- LOCK TABLES tb_volunteer write;
-- UNLOCK TABLES; -- 最后在执行
-- 【2】
-- 事务中的锁【更新】
set autocommit = 0;
begin;
update tb_volunteer set nation='回族' where user_id = 75;
commit; -- 最后执行
-- 【3】
-- 事务中的排他锁【查询】
set autocommit = 0;
begin work;
select * from tb_volunteer where user_id = 75 for update; -- 仅自己更新,其他可以查询,更新阻塞
commit work;
-- 【4】
-- 事务中的共享锁
set autocommit = 0;
begin;
SELECT * from tb_volunteer where user_id = 75 LOCK IN SHARE MODE; -- 仅多人查询,谁都不能更新
commit;
-- 聚合中的锁【5】
-- 实际上是一个表锁了
set autocommit =0;
begin;
select max(code) from tb_volunteer where age_group = 1 for update ;
update tb_volunteer set nation='壮族' where user_id = 75;
commit;
-- 【6】
-- 行锁在非索引字段时候可否
-- 即使条件字段不是索引字段,也可以上锁
set autocommit=0;
begin;
select * from tb_volunteer where id = 215 for update;
commit;
-- 【7】
-- 查询时候不加特殊条件是否阻塞
set autocommit = 0;
begin;
select * from tb_volunteer where id = 211;
commit; -- 最后执行
线程二对应(序号)的几个操作
-- 【1】
-- 若不解表锁一直阻塞
select * from tb_volunteer;
-- 【2】
-- 不commit提交事务不同线程阻塞,commit后其他线程可继续
update tb_volunteer set nation='壮族' where user_id = 25;
-- 【3】
-- 不commit提交事务他人阻塞,同线程可改,commit后其他线程继续
update tb_volunteer set nation='维吾尔族' where user_id = 75;
-- 【4】
-- 再次尝试了下,感觉和for update差别不大,别人线程都是只能读,不能写,自己线程能读能写
select * from tb_volunteer where user_id = 75; -- 【可直接执行】
update tb_volunteer set nation='彝族' where user_id = 75; -- 【commit之后才能执行】
-- 【5】
-- 聚合上锁研究
select * from tb_volunteer where age_group = 1
update tb_volunteer set nation='汉族' where user_id >75 and age_group = 2 ;
-- 【6】
-- 行锁在非索引字段时候可否【6】:可
update tb_volunteer set nation='藏族' where id = 215;
-- 【7】
-- 查询时候即使没有commit,也能更新
update tb_volunteer set nation = '壮族' where id = 211