SqlServer 中 nolock和with(nolock)

本文介绍了SQL Server中nolock的使用,它用于避免阻塞现象并提高查询效率,允许脏读。在SQL Server中,如果不加nolock,可能会发生阻塞和读取脏数据,而MySQL和Oracle默认不会。nolock与with(nolock)在SQL Server中有相同效果,但with(nolock)在指定索引时更方便。跨服务器查询时只能用nolock。

最近刚换了工作,数据库也换了,看函数的时候发现里面有nolock这个用法,例如:sleect * from table_name with(nolock)

于是搜索了很多,现在做一个总结

nolock:

其实说白了,就是数据库机制不同导致的,

MySQL、Oracle默认情况是不会发生阻塞现象,不会读取脏数据的,也就是说不会出现一行数据不完整的情况

而SqlServer不一样,如果此时有修改数据的发生,那么会进行阻塞,防止读脏,但是这样会导致时间超时,对于大量数据企业很不友好

所以为了避免阻塞现象,允许脏数据的产生,加上nolock来提高效率--一般只适用于select

NOLOCK 语句执行时不发出共享锁,允许脏读 ,等于 READ UNCOMMITTED事务隔离级别 ---参考其他博客

SQLServer 默认情况下一个事务修改了某个值,在这个事务提交前,是阻塞其他连接来读取这个修改中的值的,如果加nolock读取到的是修改后为提交的值(也就是脏读,因为可能这个值最终会回滚)

 

nolock和with(nolock):

1SQL05中的同义词,只支持with(nolock);

2with(nolock)的写法非常容易再指定索引。

3、跨服务器查询语句时不能用with (nolock) 只能用nolock,同一个服务器查询时 with(nolock)nolock都可以用

<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、付费专栏及课程。

余额充值