转载

SERIALIZABLE隔离级别下的一致性非锁定读

背景:
通常串行化隔离级别下,事物都是串行执行,读数据也会加锁,读会阻塞写,写也会阻塞读

问题:
1.串行化下事物加的是表锁吗?
2.写的事物一定会阻塞读事物吗?事物真的不会并发吗?

实验1(串行化下事物加的是行锁而不是表锁):
session 1
SERIALIZABLE隔离级别下的一致性非锁定读

session 2
SERIALIZABLE隔离级别下的一致性非锁定读
结论:串行化并不是加的表锁,而是行锁


实验2:(通常情况下,写会阻塞读,但是在autocommit=1的情况下,单条select语句并不会阻塞,而在begin或者start transaction中就会阻塞):
SERIALIZABLE隔离级别下的一致性非锁定读
session1
SERIALIZABLE隔离级别下的一致性非锁定读

session 2
SERIALIZABLE隔离级别下的一致性非锁定读SERIALIZABLE隔离级别下的一致性非锁定读
SERIALIZABLE隔离级别下的一致性非锁定读SERIALIZABLE隔离级别下的一致性非锁定读
SERIALIZABLE隔离级别下的一致性非锁定读SERIALIZABLE隔离级别下的一致性非锁定读
SERIALIZABLE隔离级别下的一致性非锁定读
分析:
这里1单条select语句没有阻塞,说明读事物不一定会被写阻塞。而2这条在事物语句中的select语句产生了阻塞,说明start transaction的查询事物跟单条select事物还是有区别。

原因:
当采用了start transaction以及begin的查询事物,就会隐式转换为SELECT ... LOCK IN SHARE MODE,所以被session1的delete语句阻塞了;而另一个非直接原因就是保证事物的可重复读,如果在start transaction后的查询语句不阻塞,那么就能在插入或者修改一条数据,接下来在事物中用同一条select再次查询,就会导致事物中第一次查询跟第二次查询的结果不一致。
而单条select语句(一个语句即事物),系统能判断它是只读性事物,所以采用一致性非锁定读。

结论:在单个select语句事物(autocommit=1)时,MySQL会采取一致性非锁定读,所以在这种条件下,事物能并发。


正文到此结束
Loading...