sqlserver 中NOLOCK、HOLDLOCK、UPDLOCK、TABLOCK、TABLOCKX

本文详细解释了 SQL Server 中的锁类型,包括 NOLOCK、HOLDLOCK、UPDLOCK、TABLOCK、TABLOCKX 的作用和区别,帮助读者理解不同锁类型对事务隔离和并发控制的影响。
sqlserver 中NOLOCK、HOLDLOCK、UPDLOCK、TABLOCK、TABLOCKX
发表于3年前  ⁄ SQL Server  ⁄ 暂无评论 ⁄ 阅读量 3,719
id="cproIframe_u2004926_1" width="336" height="280" src="http://pos.baidu.com/acom?adn=3&at=231&aurl=&cad=1&ccd=24&cec=UTF-8&cfv=17&ch=0&col=zh-CN&conBW=0&conOP=1&cpa=1&dai=1&dis=0&ltr=http%3A%2F%2Fwww.uol123.com%2Ftag%2Fholdlock&ltu=http%3A%2F%2Fwww.uol123.com%2F2012%2F02%2F15%2Fsqlserver-%25E4%25B8%25ADnolock%25E3%2580%2581holdlock%25E3%2580%2581updlock%25E3%2580%2581tablock%25E3%2580%2581tablockx.html&lu_161=0&lunum=6&n=10099028_cpr&pcs=1022x576&pis=10000x10000&ps=234x737&psr=1440x900&pss=1022x244&qn=fb08804cdea6ef0e&rad=&rsi0=336&rsi1=280&rsi5=4&rss0=%23FFFFFF&rss1=%23FFFFFF&rss2=%230000ff&rss3=%23444444&rss4=%23008000&rss5=&rss6=%23e10900&rss7=&scale=&skin=tabcloud_skin_3&stid=5&td_id=2004926&titFF=%E5%AE%8B%E4%BD%93&titFS=12&titTA=left&tn=text_default_336_280&tpr=1427968218421&ts=1&version=2.0&xuanting=0&dtm=BAIDU_DUP2_SETJSONADSLOT&dc=2&di=u2004926&tt=1427968218400.22.107.110" align="center,center" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="margin: 0px; padding: 0px; border-width: 0px; font-size: 12px; background: transparent;">

NOLOCK(不加锁) 


此选项被选中时,SQL Server 在读取或修改数据时不加任何锁。 在这种情况下,用户有可能读取到未完成事务(Uncommited Transaction)或回滚(Roll Back)中的数据, 即所谓的“脏数据”。 

HOLDLOCK(保持锁) 

此选项被选中时,SQL Server 会将此共享锁保持至整个事务结束,而不会在途中释放。 

UPDLOCK(修改锁) 

此选项被选中时,SQL Server 在读取数据时使用修改锁来代替共享锁,并将此锁保持至整个事务或命令结束。使用此选项能够保证多个进程能同时读取数据但只有该进程能修改数据。 

TABLOCK(表锁) 

此选项被选中时,SQL Server 将在整个表上置共享锁直至该命令结束。 这个选项保证其他进程只能读取而不能修改数据。 

PAGLOCK(页锁) 

此选项为默认选项, 当被选中时,SQL Server 使用共享页锁。 

TABLOCKX(排它表锁) 

此选项被选中时,SQL Server 将在整个表上置排它锁直至该命令或事务结束。这将防止其他进程读取或修改表中的数据。 



HOLDLOCK 持有共享锁,直到整个事务完成,应该在被锁对象不需要时立即释放,等于SERIALIZABLE事务隔离级别 

  NOLOCK 语句执行时不发出共享锁,允许脏读 ,等于 READ UNCOMMITTED事务隔离级别 

  PAGLOCK 在使用一个表锁的地方用多个页锁 

  READPAST 让sql server跳过任何锁定行,执行事务,适用于READ UNCOMMITTED事务隔离级别只跳过RID锁,不跳过页,区域和表锁 

  ROWLOCK 强制使用行锁 

  TABLOCKX 强制使用独占表级锁,这个锁在事务期间阻止任何其他事务使用这个表 

  UPLOCK 强制在读表时使用更新而不用共享锁 

注意: 锁定数据库的一个表的区别 

  SELECT * FROM table WITH (HOLDLOCK) 其他事务可以读取表,但不能更新删除 

  SELECT * FROM table WITH (TABLOCKX) 其他事务不能读取表,更新和删


<think>我们正在讨论SQLServer中的NOLOCK提示。根据引用内容,NOLOCK提示用于指定查询在读取数据时不使用锁,从而避免被其他事务阻塞。但同时,它允许读取未提交的数据(脏读),以及可能出现不可重复读和幻读的问题。作用:1.避免阻塞:当查询使用NOLOCK时,它不会对读取的数据加共享锁,因此不会与正在修改数据的排他锁冲突。2.提高并发性:由于不加锁,其他事务可以同时修改数据,减少了等待。负面影响:1.脏读:可能读取到未提交的数据,这些数据可能随后被回滚。2.不可重复读:在同一事务中多次读取同一数据可能得到不同结果(因为其他事务可能修改了数据)。3.幻读:可能读取到其他事务插入的新行(幻行)或删除的行。使用场景:-在需要快速读取数据且对数据一致性要求不高的场景,如生成报表或分析历史数据。-在读取的数据不会被修改(如归档数据)或可以容忍少量不一致的情况下。注意事项:-在事务性操作(如银行交易)中避免使用,因为脏读可能导致严重问题。-在跨服务器查询时,不能使用WITH(NOLOCK)语法,但可以使用NOLOCK(不加WITH)。-SQLServer2005及更高版本的同义词只支持WITH(NOLOCK)语法。示例查询:```sql--使用NOLOCK提示SELECT*FROMSales.OrdersWITH(NOLOCK)WHERECustomerID=10;--等同于设置事务隔离级别为READUNCOMMITTEDSETTRANSACTIONISOLATIONLEVELREADUNCOMMITTED;SELECT*FROMSales.OrdersWHERECustomerID=10;```总结:NOLOCK提示是一种用数据一致性换取并发性能的机制,使用时需权衡利弊。§§相关问题§§1.NOLOCK提示和设置事务隔离级别为READUNCOMMITTED有何区别?2.在哪些情况下使用NOLOCK提示是安全的?3.如何避免NOLOCK提示带来的脏读问题?4.SQLServer中除了NOLOCK还有哪些表提示?</think>### SQL Server 中 NOLOCK 提示的作用及影响 #### **作用原理** NOLOCK 提示(或 `WITH (NOLOCK)`)用于查询时**跳过共享锁机制**,允许读取未提交的数据(脏读)。其核心行为包括: 1. **避免阻塞**:当其他事务持有排他锁(如更新数据时),使用 NOLOCK 的查询不会被阻塞,可直接读取数据[^1][^3]。 - 示例:事务 A 更新数据未提交时,事务 B 使用 NOLOCK 仍能读取到 A 修改中的临时值。 2. **隔离级别等效**:功能等同于将事务隔离级别设置为 `READ UNCOMMITTED`[^2]。 3. **不生成锁**:查询过程不申请共享锁,减少锁竞争。 #### **主要影响** | **优点** | **风险** | |-----------------------------|----------------------------------| | ✅ 提升查询并发性能 | ❌ **脏读**:读取未提交数据(可能回滚)[^2] | | ✅ 减少死锁概率 | ❌ **不可重复读**:同事务多次查询结果不一致 | | ✅ 适用高并发只读场景 | ❌ **幻读**:读取到其他事务新增/删除的行 | #### **使用场景** 1. **容忍数据延迟**:报表分析、历史数据查询等非实时场景。 2. **高并发只读操作**:如大屏监控、只读从库查询。 3. **紧急排查**:当生产环境锁阻塞严重时临时使用。 #### **语法差异** ```sql -- 标准写法(推荐) SELECT * FROM Orders WITH (NOLOCK) WHERE Status = 1; -- 旧式写法(跨服务器查询时部分版本支持) SELECT * FROM Orders (NOLOCK) WHERE Status = 1; ``` > 📌 注意:SQL Server 2005+ 的同义词仅支持 `WITH (NOLOCK)` 语法[^2]。 #### **注意事项** 1. **事务一致性**:禁止在资金交易、订单处理等需强一致性的场景使用。 2. **替代方案**:考虑 `READ COMMITTED SNAPSHOT` 隔离级别,通过行版本控制避免脏读。 3. **跨服务器查询**:链接服务器查询时需用 `NOLOCK`(不加 `WITH`)[^2]。 > ⚠️ **典型风险案例**: > 事务 A 更新金额(`UPDATE Accounts SET Balance=200 WHERE ID=1`),未提交时事务 B 用 NOLOCK 读到 `Balance=200`,但 A 发生错误回滚后实际余额仍为原值,导致 B 获得错误数据[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值