锁定和阻塞

  锁是事务获取的一种控制资源,用于保护数据资源,防止其它事务对数据进行冲突的或不兼容的访问。我们目前只要学习两种基本的锁模式就可以,它们分别是共享锁和排他锁。

共享锁主要是在读操作时使用,读操作一旦完成,数据库就会立即释放资源上的共享锁,而且多个事务可以同时持有同一数据资源上的共享锁。而排他锁主要是在修改数据时使用,一旦授予,事务将一直持有排他锁,直到事务完成(提交或回滚)。对于同一数据资源,如果有其他事务已经获取了该资源的任何类型的锁,就不能再获取该资源的排他锁,如果有其他事务已经获得了该资源的排他锁,就不能再获取该资源的任何类型的锁。

  下面用一个示例来对其进行演示。首先开启一个会话 Connection 1,打开一个事务,对Production.Products表的一行进行更新,为产品2的当前单价19.00增加1.00,为了修改这一行,会话必须先获得一个排他锁。如下代码。

USE TSQLFundamentals2008;
GO

-- Connection 1,修改數據獲取排他鎖
BEGIN TRAN --開啟事務,但沒有commit,所以該會話會一直持有排他鎖

UPDATE Production.Products SET unitprice+=1.00
WHERE productid=2;

因为这个事务没有完成(没有提交或回滚),所以该会话会一直持有排他锁。此时再开启一个会话Connection 2,试图去查询这一行数据,为了读操作这个会话需要一个共享锁,但是这一行已经被前面那个会话的排他锁锁定,而且共享锁和排他锁是不兼容的,所以会话Connection 2会被阻塞,进入等待状态。如下代码。

USE TSQLFundamentals2008;
GO

-- Connection 2,查詢數據獲取共享鎖
-- 因為這一行已經被會話Connection 1所持有的排他鎖鎖定,而排他鎖和共享鎖是不兼容的,所以該會話會被阻塞
SELECT * FROM Production.Products
WHERE productid=2;

如果发生了这样的锁定和阻塞,我们就会想办法去分析和排除这种阻塞,为此,我们可以通过一些动态管理对象来得到关于锁的详细信息。如下代码。

USE TSQLFundamentals2008;
GO

-- Connection 3
-- 1,通過動態管理視圖sys.dm_tran_locks查看該數據庫阻塞鏈中進程的信息
SELECT request_session_id AS spid, --會話ID
        resource_type AS restype, -- 資源類型
        resource_database_id AS dbid, --數據庫ID
        DB_NAME(resource_database_id) AS dbname, --數據庫名稱
        resource_description AS res,--資源描述
        resource_associated_entity_id AS resid,-- 資源相關聯實體的ID
        request_mode AS mode,--鎖模式
        request_status AS STATUS --鎖狀態
FROM sys.dm_tran_locks;

-- 2,通過動態管理視圖sys.dm_exec_connections查看阻塞鏈中進程關聯的聯接信息
-- 比如联接建立的时间,最后一次发生读操作和写操作的时间以及最后执行的SQL代码
SELECT session_id AS spid,
        connect_time AS connecttime,
        last_read,
        last_write,
        text
FROM sys.dm_exec_connections
CROSS APPLY sys.dm_exec_sql_text(most_recent_sql_handle) AS ST
WHERE session_id IN(52,54);

-- 3,通过动态管理视图sys.dm_exec_sessions找到更多有用的信息
-- 包括登录的用户名,主机名和登录时间,最后请求开始时间和最后请求结束时间
SELECT session_id AS spid,
        login_time,
        host_name,
        program_name,
        nt_user_name,
        last_request_start_time,
        last_request_end_time
FROM sys.dm_exec_sessions
WHERE session_id IN(52,54);

-- 4,可通過動態管理視圖sys.dm_exec_requests查詢到導致阻塞的進程的詳細信息
SELECT session_id AS spid,
        blocking_session_id,
        command,
        sql_handle,
        database_id,
        wait_type,
        wait_time,
        wait_resource
FROM sys.dm_exec_requests
WHERE blocking_session_id>0;

-- 利用KILL<spid>命令終止導致阻塞的進程
-- 該操作會導致Connection 1中的事務回滾
KILL 51;
时间: 2024-11-11 07:53:34

锁定和阻塞的相关文章

线程、内存、锁定和阻塞(Threads, Memory, Locking, and Blocking)

如果你真的想进行并行编程的话,花点时间理解线程和内存的概念是完全值得的.在这一节,我们将学习如何显式地创建线程,并控制对共享资源,比如内存的访问.我的忠告是,应该避免你这样显式创建和管理线程,然而,在使用其他的并行编程方法时,理解底层的线程概念是需要的. 程序运行时,操作系统会创建一个进程(process)来运行,这个进程代表分配给这个程序的资源,最常见的是分配给它的内存.进程可以有一个或多个线程,负责运行程序的指令,共享进行的内存.在 .NEt 中,程序是以运行这个程序代码的线程开始的,在 F

SQL Server 的锁定和阻塞

本帖提供两种做法,可避免在 SQL Server 事务锁定时产生的不正常或长时间阻塞,让用户和程序也无限期等待,甚至引起 connection pooling 连接数超过容量. 所谓的「阻塞」,是指当一个数据库会话中的事务,正在锁定其他会话事务想要读取或修改的资源,造成这些会话发出的请求进入等待的状态.SQL Server 默认会让被阻塞的请求无限期地一直等待,直到原来的事务释放相关的锁,或直到它超时 (根据 SET LOCK_TIMEOUT,本文后续会提到).服务器关闭.进程被杀死.一般的系统

【SQL Server学习笔记】事务、锁定、阻塞、死锁

http://blog.csdn.net/sqlserverdiscovery/article/details/7712068 Column name Data type Description       blocked smallint ID of the session that is blocking the request. If this column is NULL, the request is not blocked, or the session information of

mysql数据库锁定机制

前言 为了保证数据的一致完整性,任何一个数据库都存在锁定机制.锁定机制的优劣直接应想到一个数据库系统的并发处理能力和性能,所以锁定机制的实现也就成为了各种数据库的核心技术之一.本章将对MySQL中两种使用最为频繁的存储引擎MyISAM和Innodb各自的锁定机制进行较为详细的分析. MySQL锁定机制简介 数据库锁定机制简单来说就是数据库为了保证数据的一致性而使各种共享资源在被并发访问访问变得有序所设计的一种规则.对于任何一种数据库来说都需要有相应的锁定机制,所以MySQL自然也不能例外.MyS

Asp.net项目因Session阻塞导致页面打开速度变慢

发现罪魁祸首是Session阻塞造成的.默认情况下session状态是“可写状态”(EnableSessionState=”true”),即当用户打开任何一个页面时,该页面的Session就会持有一个写锁定,写锁定会阻塞所有的读写锁定,故只有等该页面处理完毕后才释放对应的Session写锁定,在释放之前访问其他页面时将被阻塞住.详细描述如下: 当页面对Session具有可写功能(即页面有<%@ Page EnableSessionState="True" %>标记),此时直

[转载]# Ajax异步请求阻塞情况的解决办法

最近使用ExtJs4的mvc模式在开发了在线漫画的后台,因为异步请求比较多,有的回应时间长,有点短.我发现在多次并发的情况下,会造成阻塞的情况.也就是说如果回应时间长的请求还在进行中,短的请求却被挂起. 找了很多资料,最终确定是asp.net session造成的.好像php也存在此类问题. 现象:在一个网站中,当访问一个处理比较耗时的页面(A页面),页面请求还没有返回时,此时再点击访问该网站的其他页面(B页面)会出现B页面很久都没有响应和返回,直到A页面输出返回数据时才开始处理B页面的请求,造

SQL 阻塞(摘自网络)

/* 所谓的「阻塞」,是指当一个数据库会话中的事务,正在锁定其他会话事务想要读取或修改的资源, 造成这些会话发出的请求进入等待的状态.SQL Server 默认会让被阻塞的请求无限期地一直等待, 直到原来的事务释放相关的锁,或直到它超时 (根据 SET LOCK_TIMEOUT ).服务器关闭. 进程被杀死.一般的系统中,偶尔有短时间的阻塞是正常且合理的:但若设计不良的程序,就可能导致长时间的阻塞, 这样就不必要地锁定了资源,而且阻塞了其他会话欲读取或更新的需求.遇到这种情况,可能就需要手工排除

Ajax异步请求阻塞情况的解决办法

最近使用ExtJs4的mvc模式在开发了在线漫画的后台,因为异步请求比较多,有的回应时间长,有点短.我发现在多次并发的情况下,会造成阻塞的情况.也就是说如果回应时间长的请求还在进行中,短的请求却被挂起. 找了很多资料,最终确定是asp.net session造成的.好像php也存在此类问题. 现象:在一个网站中,当访问一个处理比较耗时的页面(A页面),页面请求还没有返回时,此时再点击访问该网站的其他页面(B页面)会出现B页面很久都没有响应和返回,直到A页面输出返回数据时才开始处理B页面的请求,造

MySQL锁定机制简介

MySQL锁定机制简介 数据库锁定机制简单来说就是数据库为了保证数据的一致性而使各种共享资源在被并发访问访问变得有序所设计的一种规则.对于任何一种数据库来说都需要有相应的锁定机制,所以MySQL自然也不能例外.MySQL数据库由于其自身架构的特点,存在多种数据存储引擎,每种存储引擎所针对的应用场景特点都不太一样,为了满足各自特定应用场景的需求,每种存储引擎的锁定机制都是为各自所面对的特定场景而优化设计,所以各存储引擎的锁定机制也有较大区别. 总的来说,MySQL各存储引擎使用了三种类型(级别)的