【问题标题】:SQL transaction rolls back automaticallySQL 事务自动回滚
【发布时间】:2018-08-30 08:16:57
【问题描述】:

我正在使用 Storedproc 并且 DML 语句正在 Transaction 中发生。在事务中,我们正在更新多个列,如下所示:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

BEGIN TRAN

UPDATE TBLMarket SET [YR] = NULL WHERE ImportTrnId = @pi_ImportTrnId AND [YR] = ' ';
UPDATE TBLMarket SET [TYBEG] = NULL WHERE ImportTrnId = @pi_ImportTrnId AND [TYBEG] = ' ';
UPDATE TBLMarket SET [TYEND] = NULL WHERE ImportTrnId = @pi_ImportTrnId AND [TYEND] = ' ';
UPDATE TBLMarket SET [PSEQ] = NULL WHERE ImportTrnId = @pi_ImportTrnId AND [PSEQ] = ' ';
UPDATE TBLMarket SET [CTI] = NULL WHERE ImportTrnId = @pi_ImportTrnId AND [CTI] = ' ';
UPDATE TBLMarket SET [GTI] = NULL WHERE ImportTrnId = @pi_ImportTrnId AND [GTI] = ' ';
UPDATE TBLMarket SET [PTI] = NULL WHERE ImportTrnId = @pi_ImportTrnId AND [PTI] = ' ';
UPDATE TBLMarket SET [TIPR] = NULL WHERE ImportTrnId = @pi_ImportTrnId AND [TIPR] = ' ';
UPDATE TBLMarket SET [RAR] = NULL WHERE ImportTrnId = @pi_ImportTrnId AND [RAR] = ' ';
UPDATE TBLMarket SET [TMOD_E] = NULL WHERE ImportTrnId = @pi_ImportTrnId AND [TMOD_E] = ' ';
UPDATE TBLMarket SET [ATI] = NULL WHERE ImportTrnId = @pi_ImportTrnId AND [ATI] = ' ';
UPDATE TBLMarket SET [PERC] = NULL WHERE ImportTrnId = @pi_ImportTrnId AND [PERC] = ' ';
UPDATE TBLMarket SET [PPCT] = NULL WHERE ImportTrnId = @pi_ImportTrnId AND [PPCT] = ' ';
.
.
.
.
.
-----120 update statements
.
.

COMMIT TRAN

但是当我并行运行多个事务时(我们尝试了 50 个事务),我们得到了这个错误。

“事务(进程 ID 102)在锁资源上与另一个进程死锁,并已被选为死锁牺牲品。重新运行事务。”

注意:每个事务都有不同的 @pi_ImportTrnId ,这意味着并行运行的事务永远不会尝试更新同一组行。

任何帮助/建议将不胜感激。谢谢!

【问题讨论】:

  • "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED" - 不要那样做!
  • @MitchWheat 即使在移除隔离级别后也会出现同样的问题。
  • 这个查询可以很容易地重写为单个语句。您对隔离级别做出了奇怪的选择,我猜ImportTrnId 上没有索引。
  • 顺便问一下有没有触发器?
  • 正如其他人所说 - 单个UPDATE 在这里会更受欢迎。并给它 ImportTrnIds 的 set 以使用它,而不是使用不同的 @pi_ImportTrnIds 值多次运行相同的查询

标签: sql sql-server stored-procedures transactions locking


【解决方案1】:

There are no indexes - 这就是问题所在。在ImportTrnId 列上放置一个索引, 以单语句的方式重写您的查询,删除READ UNCOMMITTER,它会运行得很好。

UPDATE t SET
  [YR] = ISNULL(NULLIF(LTRIM(t.[YR]), ''), t.[YR]),
  [TYBEG] = ISNULL(NULLIF(LTRIM(t.[TYBEG]), ''), t.[TYBEG]),
  ...
FROM TBLMarket t
WHERE ImportTrnId = @pi_ImportTrnId

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-13
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    相关资源
    最近更新 更多