锁定 SQL 服务器 table 以防止插入
Locking a SQL Server table to prevent inserts
我正在 SQL Server 2008 R2 中编写此程序:
CREATE Procedure [dbo].[SetLocalSeed](@tableName nvarchar(128))
AS
BEGIN
-- Find the primary key column name
DECLARE @pkName NVARCHAR(128)
SELECT @pkName = COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name), 'IsPrimaryKey') = 1
AND TABLE_NAME = @tableName
BEGIN TRANSACTION
-- Find the max LOCAL pk value (< 10^7) - hold the lock until the transaction completes.
DECLARE @max BIGINT
DECLARE @sql NVARCHAR(MAX) = 'SELECT @max = MAX([' + @pkName + ']) FROM [' + @tableName + '] WITH (TABLOCKX, HOLDLOCK) WHERE [' + @pkName + '] < POWER(10,7)';
EXEC sp_executeSql @sql, N'@max BIGINT OUT', @max=@max OUTPUT
-- Reset the seed to the table
DBCC CHECKIDENT(@tableName, RESEED, @max)
COMMIT
END
这是在我执行此查询和随后的身份重新播种时锁定 table 以进行插入的正确方法吗?也想知道我上面做的有没有什么问题?这将用于自定义复制环境。
TIA
SQL 服务器默认允许脏读,但不允许脏写。为防止这种情况,您需要像您所做的那样显式锁定 table。如果你不这样做,看起来你可以 运行 进入这样一种情况,即两个不同的用户可以为你的 @sql 变量获得相同的值,如果他们之前都从 table 中读取他们中的一个负责重新播种(虽然 Nick 在重新播种期间对锁的看法是正确的,但您正在重新播种上下文之外进行 select)。所以我认为你有这个权利。
您还需要查看 this,了解为什么您应该将交易包含在 SET_XACT_ABORT_ON/OFF 命令中。
您还可以考虑在 Sql 服务器中将隔离级别设置为 READ COMMITTED 以仅读取已提交的数据
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
我正在 SQL Server 2008 R2 中编写此程序:
CREATE Procedure [dbo].[SetLocalSeed](@tableName nvarchar(128))
AS
BEGIN
-- Find the primary key column name
DECLARE @pkName NVARCHAR(128)
SELECT @pkName = COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name), 'IsPrimaryKey') = 1
AND TABLE_NAME = @tableName
BEGIN TRANSACTION
-- Find the max LOCAL pk value (< 10^7) - hold the lock until the transaction completes.
DECLARE @max BIGINT
DECLARE @sql NVARCHAR(MAX) = 'SELECT @max = MAX([' + @pkName + ']) FROM [' + @tableName + '] WITH (TABLOCKX, HOLDLOCK) WHERE [' + @pkName + '] < POWER(10,7)';
EXEC sp_executeSql @sql, N'@max BIGINT OUT', @max=@max OUTPUT
-- Reset the seed to the table
DBCC CHECKIDENT(@tableName, RESEED, @max)
COMMIT
END
这是在我执行此查询和随后的身份重新播种时锁定 table 以进行插入的正确方法吗?也想知道我上面做的有没有什么问题?这将用于自定义复制环境。
TIA
SQL 服务器默认允许脏读,但不允许脏写。为防止这种情况,您需要像您所做的那样显式锁定 table。如果你不这样做,看起来你可以 运行 进入这样一种情况,即两个不同的用户可以为你的 @sql 变量获得相同的值,如果他们之前都从 table 中读取他们中的一个负责重新播种(虽然 Nick 在重新播种期间对锁的看法是正确的,但您正在重新播种上下文之外进行 select)。所以我认为你有这个权利。
您还需要查看 this,了解为什么您应该将交易包含在 SET_XACT_ABORT_ON/OFF 命令中。
您还可以考虑在 Sql 服务器中将隔离级别设置为 READ COMMITTED 以仅读取已提交的数据
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;