【问题标题】:Can I open an stoppable transaction with SQL Server?我可以使用 SQL Server 打开可停止事务吗?
【发布时间】:2011-08-03 07:24:00
【问题描述】:

我正在寻找类似于 SQL 事务的东西。我需要交易提供的常规保护,但我不希望它拖慢其他人的速度。

假设客户端 A 连接到数据库并运行这些命令:

BEGIN TRAN
SELECT (something)
(Wait a few seconds maybe.)
UPDATE (something)
COMMIT

在 SELECT 和 UPDATE 之间,客户端 B 出现并尝试进行查询,在正常情况下,最终不得不等待 A 提交。

我希望客户端 A 以这样的方式打开它的事务,如果 B 出现并执行它的查询,客户端 A 会发现它的事务立即回滚并且它的后续命令失败。客户端 B 只会遇到最小的延迟。

(请注意,SELECT 和 UPDATE 只是说明性命令。)

更新...

我有一个高优先级任务(客户端 B)有时(每月一次)会收到 SQL 超时错误,还有一个低优先级任务(客户端 A)的事务导致该超时。我宁愿低优先级的任务失败并在下一个周期重新尝试。

我最终通过完全消除事务并用一组非正式的标志替换它们来解决这个问题。查询被重构为仅在引发正确的标志集时才执行某些操作,并且我添加了一些清除回滚过去会清除的废弃记录的内容。

我通过消除交易解决了我的交易问题。

【问题讨论】:

  • 如果您的事务不重要以至于您愿意在后续命令失败的情况下接受回滚,那么为什么还要为事务烦恼呢?
  • 事务仍然会阻止半应用事务。当然,如果您想尽量减少时间,ROLLBACK 可能需要与完成交易一样长或更长的时间。
  • “我希望客户 A 向客户 B 开放其交易”——无论从商业角度还是从技术角度来看,这种期望都是没有意义的。它与交易的基本含义相矛盾。
  • @Joe - 比起我的低优先级任务完成时,我可能更关心不保留高优先级任务。
  • @blspr - 相反,这很有意义。 :) B 绝不会进入 A 打开的事务。这就像事务被网络故障中断,数据库会尽职尽责地回滚所有未提交的内容并释放等待查询的块。

标签: sql sql-server transactions


【解决方案1】:

使用SNAPSHOT 隔离级别将防止B 阻塞。 B 将看到处于A 发布BEGIN TRANSACTION 之前状态的数据。除非B修改数据,否则它们永远不会互相阻塞。

【讨论】:

  • 这是一个很好的解决方案。使用这种隔离级别,“作者不会阻止读者”。
【解决方案2】:

虽然根本不是事务Optimistic Concurrency 可能很有用——它在 LINQ2SQL 等中默认使用。

一般的想法是读取数据 - 可以独立进行修改 - 然后使用“检查”写回数据(这与比较和交换大致可比)。如果检查失败,则由应用程序决定要做什么(重新启动进程,继续进行,失败)。

这自然不适用于所有场景,并且可能无法检测到许多交互,例如在“读取”和“写入”之间添加的新项目。实际的读取和写入都可以在具有适当隔离级别的单独事务中;单独的事务可能允许其他事务交错。

当然,取决于具体的问题和交互...不同的隔离级别和/或更细粒度的锁定可能就足够了。

编码愉快。

【讨论】:

  • 我的一系列标志(请参阅有问题的更新)与您描述的效果非常相似。
【解决方案3】:

那是从前到后。

你不能让后来的客户中止早期的交易:那是混乱。

您可以使用snapshot isolation,以便客户端 B 具有一致的视图并且不会(大部分)被客户端 A 阻止。也可以使用Wikipedia 获取更一般的内容

或许可以更全面地描述您的问题,以便我们为此提供建议...

【讨论】:

  • @billpg:如果它每月运行它不是高优先级。以及为什么您的 TXN 需要这么长时间才能导致超时。你已经破解了交易以隐藏设计、查询或索引中的缺陷。或以上所有。
  • 不,它每分钟运行一次。当最坏的情况随机发生时,每月都会发生超时失败。事务需要很长时间,因为在同一个数据库上的多台机器上进行了大量处理。
  • @billpg:增加你的超时时间。我误读了它,但您仍然在为每月一次的事件破坏您的交易和数据完整性。不管怎样,这是你的数据库,不是我的……
【解决方案4】:

我见过使用的一件事(但我担心我没有任何方便的代码)是让事务 A 产生另一个进程,然后监视该事务。如果它看到由事务引起的任何块,则立即向 spid 发出KILL

如果我能找到此代码,我会在此处添加。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2015-04-10
    • 1970-01-01
    相关资源
    最近更新 更多