我正在编写一个连接到 sql server 并对表执行更新操作的 Windows 应用程序。
已经有另一个名为 P2 的程序正在更改同一个表中的数据。所以表被锁定
从我的应用程序访问表时出现错误
我需要一个解决方案,其中程序首先检查表是否已锁定,如果表未锁定,则必须更新数据。如果表已经被锁定,那么它必须等待一段时间并重试该操作。
谁能给我一份??
我正在编写一个连接到 sql server 并对表执行更新操作的 Windows 应用程序。
已经有另一个名为 P2 的程序正在更改同一个表中的数据。所以表被锁定
从我的应用程序访问表时出现错误
我需要一个解决方案,其中程序首先检查表是否已锁定,如果表未锁定,则必须更新数据。如果表已经被锁定,那么它必须等待一段时间并重试该操作。
谁能给我一份??
在执行操作之前检查某些东西是否被锁定绝不是一个好主意。因为可以在执行检查之后和执行更新之前获取锁:
if(noLockOnTheTable)
{
// ... something else acquires the lock just at this point
updateTable();
}
所以尝试检查锁是徒劳的。您应该继续尝试获取锁并立即执行更新。您可能会避免这种情况,因为其他操作花费的时间太长并且您不希望用户等待。在这种情况下,您可以指定“短锁定等待超时”并向用户提供一条消息,说明“稍后再试”。用户无需等待。
您可以尝试以下方法:
CREATE TABLE #lockTable
(
[spid] smallint
, [dbid] smallint
, [objid] int
, [indid] smallint
, [type] nchar(4)
, [resource] nchar(32)
, [mode] nvarchar(8)
, [status] nvarchar(5)
);
INSERT INTO #lockTable EXEC sp_lock;
SELECT * FROM #lockTable WHERE objeid = OBJECT_ID('mytable');
DROP TABLE #lockTable;
例如-在当前会话中获取锁:
create table dbo.test (i int)
Go
begin tran
insert into dbo.test With (tablock) (i) values (1)
Go
Select
DB_NAME(tl.resource_database_id) database_name,
tl.resource_type,
case when resource_type = 'OBJECT' then OBJECT_NAME(tl.resource_associated_entity_id) Else null End ObjectName,
tl.resource_type,
tl.request_mode,
tl.request_status,
tl.*
From sys.dm_tran_locks tl
Where request_session_id = @@SPID
order by case when resource_type = 'OBJECT' then OBJECT_NAME(tl.resource_associated_entity_id) Else null End,
tl.request_mode, tl.resource_type
Rollback