相关疑难解决方法(0)

使用 SELECT-UPDATE 模式时管理并发

假设您有以下代码(请忽略它很糟糕):

BEGIN TRAN;
DECLARE @id int
SELECT @id = id + 1 FROM TableA;
UPDATE TableA SET id = @id; --TableA must have only one row, apparently!
COMMIT TRAN;
-- @id is returned to the client or used somewhere else
Run Code Online (Sandbox Code Playgroud)

在我看来,这不是正确管理并发性。仅仅因为您有一个事务并不意味着其他人不会读取您在获取更新语句之前所做的相同值。

现在,让代码保持原样(我意识到这作为单个语句更好地处理,甚至使用自动增量/标识列更好)有哪些确定的方法可以使其正确处理并发并防止允许两个客户端获得相同条件的竞争条件身份证价值?

我很确定将 a 添加WITH (UPDLOCK, HOLDLOCK)到 SELECT 会解决问题。该SERIALIZABLE事务隔离级别(因为它拒绝任何人阅读你做了什么,直到移植是在将似乎工作,以及UPDATE:这是假见马丁的答案)。真的吗?它们会同样有效吗?一个比另一个更受欢迎吗?

想象一下做一些比 ID 更新更合法的事情——一些基于你需要更新的读取的计算。可能涉及许多表,其中一些您会写入,而另一些则不会。这里的最佳做法是什么?

写完这个问题后,我认为锁定提示更好,因为这样你只锁定了你需要的表,但我很感激任何人的意见。

PS 不,我不知道最好的答案,真的很想得到更好的理解!:)

sql-server concurrency locking isolation-level

26
推荐指数
3
解决办法
1万
查看次数

为什么在“插入查询”之前“开始事务”会锁定整个表?

我正在使用 SQL Server 2005 Express。

在一个场景中,我在存储过程中Begin TransactionINSERT语句之前添加了命令。当我执行这个存储过程时,它锁定了整个表,所有并发连接都显示挂起,直到INSERT完成。

为什么整个表都被锁定了,我如何在 SQL Server 2005 Express 中解决这个问题?

已编辑

查询如下:

INSERT INTO <table2> SELECT * FROM <table1> WHERE table1.workCompleted = 'NO'
Run Code Online (Sandbox Code Playgroud)

sql-server-2005

11
推荐指数
2
解决办法
3万
查看次数