事务,锁,隔离级别

时间:2011-09-17 20:39:38

标签: transactions locking isolation-level

我对标题中的主题有几个问题。首先,假设我们使用JDBC,并且我们有2个事务T1和T2。在T1中,我们在一个特定行上执行select语句。然后我们在该行上执行更新。在事务T2中,我们在同一行上执行select语句。

以下是问题:

1)事务T1何时获取上述行的锁定?我假设它发生在select语句执行期间?

2)事务T1保持锁多长时间?它是否在提交/回滚事务之前保留它,或者在此之前释放锁定?

3)隔离级别是否控制使用哪种类型的锁?例如:

a)如果我们在事务T2上使用读取提交隔离级别,这是否意味着T2将对select语句使用共享读锁定,以便在T1更新的情况下已经T2的行将不具有访问该行(避免脏读),如果T1没有更新行,T2还是对该行有读访问权限吗?

b)如果我们在事务T2上使用读取未提交的隔离级别,这是否意味着T2将对select语句使用no-lock,因此即使它被T1修改,它也可以读取数据(允许脏读)。

所以,最让我烦恼的问题是谁能控制决定使用什么类型的锁?是隔离级别的交易,还是有其他方式?

4)如果对问题3的回答是肯定的(隔离级别控制使用的是什么锁),那么如果我们使用jdbc而不是mysql数据库会发生什么,我们使用select for update或select share in share mode constructs?我记得第一个是独占锁,而第二个是共享读锁。它将如何反映我们的事务隔离级别?

5)在可重复读取隔离级别的情况下获得了什么样的锁定?假设我们的T2(具有可重复的读隔离级别)在同一行上有两个select语句,而T1与之前相同。首先在T2中执行一个select语句,然后执行并提交T1,然后执行T2第二次选择。这种情况甚至可能吗?如果事务保持锁定直到它们被提交/回滚,我假设T1在T2完成之前将无法获得排除更新的独占锁定?

编辑:还有一个问题:

6)在多版本并发控制系统中,当我们设置 serializable 隔离级别时,事务A试图更新由另一个事务B更新的某一行(B在A启动后更新了行)将被退回。我想问一下在乐观锁定场景中发生的事情是不是很相同?

提前致谢。

1 个答案:

答案 0 :(得分:2)

你的问题很好。了解获取哪种锁可以深入理解DBMS。在SQL Server中,在所有隔离级别下(Read Uncommitted,Read Committed(默认),Repeatable Reads,Serializable)为Write操作获取独占锁。

无论隔离级别如何,当事务结束时都会释放独占锁。

隔离级别之间的差异是指获取/释放共享(读取)锁定的方式。

在Read Uncommitted隔离级别下,不会获取共享锁。在此隔离级别下,可能会发生称为“脏读”的并发问题。

在Read Committed隔离级别下,为相关记录获取共享锁。当前指令结束时释放共享锁。此隔离级别可防止“脏读”,但由于记录可由其他并发事务更新,因此可能会发生“不可重复读取”或“幻像读取”。

在“可重复读取”隔离级别下,将为事务持续时间获取共享锁。防止“脏读”和“不可重复读”,但仍可能出现“幻读”。

在Serializable隔离级别下,将为事务持续时间获取范围内的共享锁。上述并发问题均未发生,但性能大幅降低,存在死锁发生的风险。