【问题标题】:Not sure about the type of SQL Server lock to use for synchronization不确定用于同步的 SQL Server 锁的类型
【发布时间】:2023-04-07 15:36:01
【问题描述】:

我有一个 ASP.NET Web 应用程序,它像这样填充 SQL Server 2008 数据库表:

INSERT INTO tblName1 (col1, col2, col3)
VALUES(1, 2, 3)

我还有一个单独的服务应用程序,它通过首先重命名该表,然后创建一个空表来处理该表的内容(在后台):

SET XACT_ABORT ON
BEGIN TRANSACTION

--Rename table
EXEC sp_rename 'tblName1', 'temp_tblName1'

--Create new table
CREATE TABLE tblName1(
id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
col1 INT,
col2 INT,
col3 INT
)
COMMIT

SET XACT_ABORT OFF
--Begin working with the 'temp_tblName1' table

我不确定在这种情况下我需要在tblName1 表上使用哪个 SQL 锁?

PS。为您提供这两个代码示例的运行频率:第一个可能每秒运行几次(尽管大多数时候,频率较低),第二个 - 一天两次。

【问题讨论】:

  • 我不知道你所说的“锁”是什么意思,但这听起来像Transact-SQL
  • 是的,它是 t-SQL。我更新了标签。 “锁”是指同时访问tblName1 表的同步锁。
  • INSERT 在重命名和CREATE 之间CREATE 之间恰好到达服务器的次数可能是微乎其微的——在某种程度上其他错误(例如机器之间的网络连接丢失)更有可能 - 所以只需编写一些强大的错误处理并忽略这种特殊情况(或者,如果您正在构建下一个世界主导网站,请使用企业版和分区表,并且永远不要进行重命名/创建)
  • 我可能会找到一种不需要显式锁定的方法来执行此操作(例如将数据保存在具有状态列的单个表中,并允许 SQL Server 放置自己的行/表锁),但如果你必须明确锁定 sp_getapplock 可能会做你想做的事。
  • 如果我是你,我不会重命名表。 1)在第一次处理中继续插入到表中; 2)在进行第二个过程时,大约每天两次,“记住”你应该使用的数据(即使用 id)。处理后,清除数据。这样就不用担心锁了。

标签: asp.net sql-server sql-server-2008 tsql synchronization


【解决方案1】:

正如一些 cmets 所建议的,请考虑以不同的方式执行此操作。您可能会受益于使用snapshot isolation level。使用快照隔离需要在数据库上将ALLOW_SNAPSHOT_ISOLATION 设置为ON。此设置默认关闭,因此您需要检查是否可以将其打开。

一旦您能够使用快照隔离,您就不需要更改 INSERT 语句,但您的其他进程可能会更改为:

SET XACT_ABORT ON
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
BEGIN TRANSACTION

-- Do whatever this process does, but don't rename the table.

-- If you want to get rid of the old records:
DELETE [tblName1] WHERE 1 = 1
-- Then
COMMIT TRANSACTION

如果由于某种原因确实需要创建新的非临时表,则可能需要在进入事务之前创建,因为在快照隔离期间允许您执行的操作有一些限制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 2010-12-26
    • 1970-01-01
    相关资源
    最近更新 更多