测试环境数据库的隔离级别为 rc(READ COMMITTED)
设置数据库隔离级别
show variables like '%isolation';
SET session TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET session TRANSACTION ISOLATION LEVEL REPEATABLE READ;
set global transaction isolation level REPEATABLE READ;
set global transaction isolation level READ COMMITTED;
set global transaction isolation level READ UNCOMMITTED;
set global transaction isolation level SERIALIZABLE;
一、for update 不带where条件, 锁表
START TRANSACTION;
select * from user_t for update;
测试完记得执行commit, 否则锁表了。
二、for update 带where条件
情况1, 接where条件后的数据不存在, 不会锁表。 (这个跟想象中的不太一样)
情况2, 接where条件后有数据,分以下两种情况
- 命中索引, 行级锁。
- 不命中索引, 锁表。
三、事务里update
如果update的数据存在,分以下两种情况
- 命中索引, 行级锁。
- 不命中索引, 锁表。
跟上面for update一样。
总结, 只要update加入事务, 如果命中索引, 行级锁, 如果未命中索引且有数据命中, 锁表。
所以用数据库当做计数器时, 如果用的是行级锁, 首次插入数据时, 这个时候是线程不安全的。