2011-09-17 187 views
3

我有几个关于题目题目的问题。首先,让我们假设我们使用JDBC,并且我们有2个事务T1和T2。在T1中,我们在一个特定的行上执行select语句。然后我们对该行执行更新。在事务T2中,我们在同一行执行select语句。交易,锁,隔离级别

这里有几个问题:

1)什么时候交易T1收购上提到的行上的锁?我假设它在选择语句执行期间发生?

2)事务T1持有多长时间锁?在事务提交/回滚之前是否持有它,还是在此之前释放锁?

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

a)如果我们使用读提交事务T2的隔离级别,这是否意味着T2将使用SELECT语句的共享读锁定,以便在T1更新行之后T2将不会访问到那一行(避免脏读),并且在T1没有更新行的情况下,T2将具有对该行的读访问权限?

B)如果我们使用读事务T2提交隔离级别,这是否意味着T2将采用无锁的SELECT语句,所以它可以读取数据,即使它是由T1修改(允许脏读)。

所以,我最担心的问题是谁在控制决定应用什么类型的锁?它是交易的隔离级别,还是有其他方法?如果对问题3的回答是肯定的(隔离级别控制着什么锁使用),那么如果我们在mysql数据库上使用jdbc例如,我们使用select来更新或选择共享模式结构中的锁,会发生什么?正如我记得第一个是排他锁,而第二个是共享读锁。它将如何反映我们的事务隔离级别?

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

EDIT:还有一个问题:

6)在多版本并发控制系统中,当我们设置序列化隔离级别,事务A即试图更新一些行由另一个事务B更新(B更新A开始后的行)将被回滚。我想问的是,在乐观锁定情况下发生的事情不是那么相似吗?

在此先感谢。

+1

这是很多问题......答案取决于所使用的具体数据库/版本......所以我们在谈论什么数据库? – Yahia

+0

好吧,让我们说它是MySQL 5.5 :) – Kovasandra

+0

好吧 - 这不是enogh,因为MySQL可以用于不同的存储引擎,而这些存储引擎又对交易表现出很大的不同,所以:什么是存储引擎? – Yahia

回答

1

你的问题是一个很好的问题。了解获取何种类型的锁可以深入理解DBMS。在SQL Server中,在所有隔离级别(读取未提交,读取提交(默认),可重复读取,可序列化)下,执行写入操作的独占锁定。

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

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

在读取未提交隔离级别下,不会收集共享锁。在此隔离级别下,可能会发生称为“脏读”的并发问题。

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

在可重复读取隔离级别下,获取交易持续时间的共享锁。可以防止“脏读”和“不可重复读”,但仍然可以发生“幻像读”。

在可序列化的隔离级别下,范围内的共享锁是在事务持续时间内获取的。没有发生上述并发问题,但性能大幅降低,存在发生死锁的风险。