如果客户端需要很长时间才能接收数据,然后向SQL Server发送确认已接收到数据的通知,则SQL Server必须等待,由于此等待,除非从客户端接收到确认,否则SQL Server不会释放查询所持有的锁。
这是不准确的,它取决于隔离级别。
默认情况下READ COMMITTED
,在语句执行期间不保留锁。READ COMMITTED
不提供语句级别的读取一致性,唯一的保证是您无法读取未提交的数据。获取共享锁并将其保留以读取该行,然后释放。
除非您有LOB类型。
可能非常大的LOB类型无法缓冲。必须获取并持有共享锁,直到语句完成为止,从本质上讲,您REPEATABLE READ
在处具有行为READ COMMITTED
。
如果我要通过高延迟网络对MSSQL数据库进行一次调用,是否会由于该延迟而发生表锁定?
延迟不会导致表锁定,不会。但是,如果已获取表锁,则等待时间将延长。
引用比我更了解此机制的人(@RemusRusanu):
随着执行的进行,结果将返回给客户端程序。当行在执行树上“冒泡”时,通常需要顶层运算符负责将这些行写入网络缓冲区,并将其发送回客户端。结果不会首先创建到某个中间存储(内存或磁盘)中,然后再发送回客户端,而是将其返回到创建时的状态(在查询执行时)。将结果发送回客户端当然取决于网络流量控制协议。如果客户端没有主动使用结果(例如,通过调用SqlDataReader.Read()),则最终流控制将不得不阻止发送方(正在执行的查询),这又将中止执行查询。[资源]
由于客户端或网络的原因,结果无法像SQL Server所提供的那样快地消耗掉,我们看到了ASYNC_NETWORK_IO
等待的积累。重申一下,这不会影响所获取的锁,只会影响其持有的持续时间。
nolock
提示,否则总会有一个锁。延迟仅确定锁定将保持多长时间。