`
xinklabi
  • 浏览: 1579442 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
文章分类
社区版块
存档分类
最新评论

SQL并发会出现的问题,事务隔离级别和锁机制

 
阅读更多

NOLOCKREADPAST的区别。

1.       开启一个事务执行插入数据的操作。

BEGIN TRAN t

INSERT INTO Customer

SELECT 'a','a'

2.       执行一条查询语句。

SELECT * FROM Customer WITH (NOLOCK)

结果中显示”a””a”。当1中事务回滚后,那么a将成为脏数据。(:1中的事务未提交) NOLOCK表明没有对数据表添加共享锁以阻止其它事务对数据表数据的修改。

SELECT * FROM Customer

这条语句将一直死锁,直到排他锁解除或者锁超时为止。(:设置锁超时SET LOCK_TIMEOUT 1800)

SELECT * FROM Customer WITH (READPAST)

这条语句将显示a未提交前的状态,但不锁定整个表。这个提示指明数据库引擎返回结果时忽略加锁的行或数据页。

3.       执行一条插入语句。

BEGIN TRAN t

INSERT INTO Customer

SELECT 'b','b'

COMMIT TRAN t

这个时候,即使步骤1的事务回滚,那么a这条数据将丢失,而b继续插入数据库中。 

 

NOLOCK

1. 执行如下语句。

BEGIN TRAN ttt

SELECT * FROM Customer WITH (NOLOCK)

WAITFOR delay '00:00:20'

COMMIT TRAN ttt

注:NOLOCK不加任何锁,可以增删查改而不锁定。

INSERT INTO Customer SELECT 'a','b' –不锁定

DELETE Customer where ID=1 不锁定

SELECT * FROM Customer 不锁定

UPDATE Customer SET Title='aa' WHERE ID=1 不锁定

 

ROWLOCK

1.       执行一条带行锁的查询语句。

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ -- (必须)

BEGIN TRAN ttt

SELECT * FROM Customer WITH (ROWLOCK) WHERE ID=17

WAITFOR delay '00:00:20'

COMMIT TRAN ttt

注:在删除和更新正在查询的数据时,会锁定数据。对其他未查询的行和增加,查询数据无影响。

INSERT INTO Customer SELECT 'a','b' –不等待

 

DELETE Customer where ID=17 –等待

DELETE Customer where ID<>17 –不等待

 

SELECT * FROM Customer –不等待

 

UPDATE Customer SET Title='aa' WHERE ID=17–等待

UPDATE Customer SET Title='aa' WHERE ID<>17–不等待

 

 

HOLDLOCKTABLOCKTABLOCKX

1.       执行HOLDLOCK

BEGIN TRAN ttt

SELECT * FROM Customer WITH (HOLDLOCK)

WAITFOR delay '00:00:10'

COMMIT TRAN ttt

注:其他事务可以读取表,但不能更新删除  

update Customer set Title='aa' 要等待10秒中。

SELECT * FROM Customer —不需要等待

 

2.       执行TABLOCKX

BEGIN TRAN ttt

SELECT * FROM Customer WITH (TABLOCKX)

WAITFOR delay '00:00:10'

COMMIT TRAN ttt

注:其他事务不能读取表,更新和删除

update Customer set Title='aa' 要等待10秒中。

SELECT * FROM Customer —要等待10秒中。

 

3. 执行TABLOCK

BEGIN TRAN ttt

SELECT * FROM Customer WITH (TABLOCK)

WAITFOR delay '00:00:10'

COMMIT TRAN ttt

注:其他事务可以读取表,但不能更新删除  

update Customer set Title='aa' 要等待10秒中。

SELECT * FROM Customer —不需要等待

 

UDPLOCK

1.       A连接中执行。

BEGIN TRAN ttt

SELECT * FROM Customer WITH (UPDLOCK)

WAITFOR delay '00:00:10'

COMMIT TRAN ttt

2.       在其他连接中执行。

update Customer set Title='aa' where ID=1—要等10

SELECT * FROM Customer –不用等

insert into Customer select 'a','b'不用等

注:对于UDPLOCK锁,只对更新数据锁定。

 

注:使用这些选项将使系统忽略原先在SET语句设定的事务隔离级别(SET Transaction Isolation Level)

 

 

事务隔离级别

 

脏读:READ UNCOMMITTED

脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

1.       A连接中执行。

BEGIN TRAN t

INSERT INTO Customer

SELECT '123','123'

WAITFOR delay '00:00:20'

COMMIT TRAN t

2.       B连接中执行。

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT * FROM Customer

这个时候,未提交的数据会’123’会显示出来,当A事务回滚时就导致了脏数据。相当于(NOLOCK)

 

提交读:READ COMMITTED

1.       A连接中执行。

BEGIN TRAN t

INSERT INTO Customer

SELECT '123','123'

WAITFOR delay '00:00:20'

COMMIT TRAN t

2.       B连接中执行。

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

SELECT * FROM Customer

这个时候,未提交的数据会’123’不会显示出来,当A事务提交以后B中才能读取到数据。避免了脏读。

 

不可重复读:REPEATABLE READ

不可重复读是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

例如:

1.       A连接中执行如下语句。

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

BEGIN TRAN ttt

SELECT * FROM Customer WHERE ID=17

WAITFOR delay '00:00:30'

SELECT * FROM Customer WHERE ID=17

COMMIT TRAN ttt

2.       B连接中执行如下语句,而且要在第一个事物的三十秒等待内。

UPDATE Customer SET Title='d' WHERE ID=17

这个时候,此连接将锁住不能执行,一直等到A连接结束为止。而且A连接中两次读取到的数据相同,不受B连接干扰。

注,对于Read CommittedRead UnCommitted情况下,B连接不会锁住,等到A连接执行完以后,两条查询语句结果不同,即第二条查询的Title变成了d

 

序列化读:SERIALIZABLE

1.       A连接中执行。

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN t

UPDATE Customer SET Title='111'

WAITFOR delay '00:00:20'

COMMIT TRAN t

2. B连接中执行,并且要在A执行后的20秒内。

BEGIN TRAN tt

INSERT INTO Customer

SELECT '2','2'

COMMIT TRAN tt

A连接的事务提交之前,B连接无法插入数据到表中,这就避免了幻觉读。

 

注:幻觉读是指当事务不是独立执行时发生的一种现象,例如 第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好像发生了幻觉一样。

 

 

共享锁

共享锁(S 锁)允许并发事务在封闭式并发控制(请参阅并发控制的类型)下读取 (SELECT) 资源。资源上存在共享锁(S 锁)时,任何其他事务都不能修改数据。读取操作一完成,就立即释放资源上的共享锁(S 锁),除非将事务隔离级别设置为可重复读或更高级别,或者在事务持续时间内用锁定提示保留共享锁(S 锁)。

 

更新锁

更新锁(U 锁)可以防止常见的死锁。在可重复读或可序列化事务中,此事务读取数据 [获取资源(页或行)的共享锁(S 锁)],然后修改数据 [此操作要求锁转换为排他锁(X 锁)]。如果两个事务获得了资源上的共享模式锁,然后试图同时更新数据,则一个事务尝试将锁转换为排他锁(X 锁)。共享模式到排他锁的转换必须等待一段时间,因为一个事务的排他锁与其他事务的共享模式锁不兼容;发生锁等待。第二个事务试图获取排他锁(X 锁)以进行更新。由于两个事务都要转换为排他锁(X 锁),并且每个事务都等待另一个事务释放共享模式锁,因此发生死锁。

 

若要避免这种潜在的死锁问题,请使用更新锁(U 锁)。一次只有一个事务可以获得资源的更新锁(U 锁)。如果事务修改资源,则更新锁(U 锁)转换为排他锁(X 锁)。

 

排他锁

排他锁(X 锁)可以防止并发事务对资源进行访问。使用排他锁(X 锁)时,任何其他事务都无法修改数据;仅在使用 NOLOCK 提示或未提交读隔离级别时才会进行读取操作。

 

数据修改语句(如 INSERTUPDATE DELETE)合并了修改和读取操作。语句在执行所需的修改操作之前首先执行读取操作以获取数据。因此,数据修改语句通常请求共享锁和排他锁。例如,UPDATE 语句可能根据与一个表的联接修改另一个表中的行。在此情况下,除了请求更新行上的排他锁之外,UPDATE 语句还将请求在联接表中读取的行上的共享锁。

分享到:
评论

相关推荐

    06-VIP-深入理解Mysql事务隔离级别与锁机制.pdf

    在并发事务处理过程中,可能会出现更新丢失、脏读、不可重复读和幻读等问题。这些问题都是由于多事务并发执行引起的,需要通过事务隔离机制和锁机制来解决。 事务隔离级别 数据库的事务隔离级别是用来解决读一致性...

    SQLserver锁和事务隔离级别的比较与使用

    SQL Server的锁机制和事务隔离级别是数据库管理系统中确保数据一致性、避免并发问题的重要机制。在SQL Server中,锁主要用于控制多个用户同时访问同一数据时的并发操作,而事务隔离级别则是确定在事务中如何处理这些...

    详解Mysql事务隔离级别与锁机制.doc

    详解Mysql事务隔离级别与锁机制 ...Mysql事务隔离级别与锁机制是数据库系统中的一种机制,用于解决多事务并发问题和数据并发访问的一致性问题。了解这些机制对数据库系统的设计和实现有重要的参考价值。

    SQLserver锁和事务隔离级别的比较与使用[定义].pdf

    SQL Server 锁和事务隔离级别的比较与使用 在数据库系统中,锁和事务隔离级别是两个非常重要的概念,它们之间存在着紧密的关系。在本文中,我们将对 SQL Server 锁和事务隔离级别进行比较和使用的介绍。 首先,让...

    怎么理解SQL SERVER中事务隔离级别及相应封锁机制.pdf

    SQL Server中事务隔离级别和封锁机制是数据库管理系统中两个重要的概念,它们决定了事务之间的并发执行和数据的一致性。根据不同的应用场景,选择适合的事务隔离级别和封锁机制,可以确保数据的一致性和隔离性,提高...

    SQLSERVER事务隔离级别的实验研究.pdf

    本研究为中国工程物理研究院工学院的课题研究提供了参考和指导,通过对SQL Server事务隔离级别的实验研究,有助于理解和掌握多用户并发数据库系统中的事务隔离机制,为数据库设计和应用开发提供了科学依据。...

    SQL Server 2002中的事务隔离级别.pdf

    SQL Server 2002中的事务隔离级别是数据库管理系统中非常关键的概念,它涉及到多用户同时访问数据库时的数据一致性与并发性控制。事务是数据库操作的基本单元,它保证了一组数据库操作要么全部成功,要么全部回滚,...

    SQL Server 2000完结篇系列之三:数据并发-彻底掌握SQL Server 2000事务机制

    通过合理设置事务隔离级别,适当地使用锁定和快照隔离,以及理解和处理死锁,可以确保系统的高效运行和数据的正确性。 在实际应用中,开发者还应考虑性能因素,如事务的粒度大小、锁的类型和持续时间等,以平衡并发...

    spring事务的传播特性和事务隔离级别

    ### Spring事务的传播特性和事务隔离级别 #### 一、Spring事务的传播特性(Propagation) 在Spring框架中,事务管理不仅提供了ACID属性的支持,还引入了事务的传播特性,这些特性决定了当一个方法调用另一个方法时,...

    MySQL的四种事务隔离级别

    MySQL数据库管理系统提供了四种事务隔离级别来处理事务并发中可能遇到的问题。事务并发问题通常包括脏读、不可重复读和幻读。 一、事务的基本要素(ACID) 事务具有四个基本要素,即原子性(Atomicity)、一致性...

    SQL Server 的事务和锁

    同时,根据业务需求选择合适的事务隔离级别和锁类型,可以有效提高系统并发性能,防止数据异常。 综上所述,SQL Server的事务和锁机制是数据库管理的核心部分,它们保证了数据的准确性和一致性,为复杂的企业级应用...

    关于SQL Server事务隔离级别的探讨.pdf

    SQL Server事务隔离级别是数据库管理系统中非常重要的一个概念,它主要用于控制并发事务的执行,确保数据的一致性和完整性。事务隔离级别可以避免并发事务中的各种问题,如脏读、不可重复读和幻读。了解和应用不同的...

    sql server锁机制

    SQL Server的锁机制是数据库管理系统中用于控制并发访问和维护数据完整性的重要机制...根据应用需求,开发人员和DBA可以配置事务隔离级别、选择合适的锁定策略,以及利用事务和锁定机制来确保数据库的稳定性和安全性。

    数据库_事务隔离级别与锁.docx

    ### 数据库事务隔离级别与锁 #### 一、事务的基本特征 事务是数据库管理系统的核心概念之一,用于确保数据的一致性和正确性。事务通常具备以下四个特性,即ACID特性: 1. **原子性(Atomicity)**:事务被视为一...

    SQLServer锁机制探究

    SQL Server的锁机制是数据库管理系统中用于确保数据一致性、避免并发操作冲突的重要机制。...在实际应用中,需要根据业务需求和并发情况,选择合适的事务隔离级别和锁策略,以达到最佳的并发性能和数据完整性。

    SQL server 中锁机制详解

    事务隔离级别缺省情况下,SQL Server 采用保守的方法(悲观锁)来进行并发控制。Oracle 使用乐观锁作为缺省。决定悲观锁还是乐观锁的直接因素:被访问的数据集的大小和参与访问的用户数目。 SQL Server 中采用悲观...

    4种事务的隔离级别

    事务的隔离级别是数据库管理系统确保数据一致性的重要机制,它解决了并发事务执行时可能出现的问题,如读脏、不可重复读和幻读。在SQL92标准中,定义了四种事务隔离级别,分别是读未提交(Read Uncommitted)、读...

    MS SQL Server数据库事务锁机制分析

    事务隔离级别也是SQL Server中控制锁行为的关键因素,不同的隔离级别(如读未提交、读已提交、可重复读和串行化)会影响事务看到的数据版本和锁的使用。例如,较高的隔离级别可能会使用更多的锁来防止脏读、不可重复...

Global site tag (gtag.js) - Google Analytics