【问题标题】:Recover from SQL batch-abort errors inside a transaction? Alternative?从事务中的 SQL 批处理中止错误中恢复?选择?
【发布时间】:2009-11-11 22:03:26
【问题描述】:

我正在寻找一种方法来继续执行事务,尽管在插入低优先级数据时出现错误。看起来真正的嵌套事务可能是一种解决方案,但 SQL Server 2005/2008 不支持它们。另一种解决方案是有逻辑来确定错误是否严重,但这似乎也不可能。

下面是我的场景的更多细节:

使用 ADO.NET/C# 定期将数据插入到数据库中,虽然其中一些很重要,但也有一些可能毫无问题地丢失。插入完成后,将对数据进行一些计算。 (重要的和非重要的)整个过程都在一个事务中,所以一切都保持同步。

目前,使用事务保存点,并对非重要插入期间发生的异常进行部分回滚。但是,这不适用于“批量中止”错误,它会自动回滚整个事务。我知道有些错误很严重,但是 SQL Server 将失败的强制转换等错误视为批处理中止错误。 (Info on batch errors) 如果这些错误发生在低优先级数据上,我会尝试防止这些错误导致整个插入中断。

如果我所描述的不可行,我愿意考虑任何替代方法来实现数据完整性,但允许非重要插入失败。

感谢您的帮助。

【问题讨论】:

    标签: sql ado.net error-handling transactions rollback


    【解决方案1】:

    不幸的是,无法按照您的描述完成(对嵌套事务的完全支持将是关键)。我能想到的几件事过去曾被用来解决这个问题:

    1. 最好的选择可能是将命令分成重要/不重要的命令,可以清楚地执行,这自然要求它们彼此不依赖于顺序

    2. 还可以使用基于消息传递的方法(请参阅Service Broker),您可以内联执行主要命令并将非主要命令推送到队列中以便稍后/单独执行。推送到队列将是批处理中的事务,但是当您从队列中弹出时命令的执行将是分开的。这也要求它们彼此之间不依赖于顺序。

    3. 1234563为了以及为每种“类型”的操作(即主要与非主要)使用单独的事务。如果所有分组消息都必须是单个自主操作,那么这将需要您进行一些特殊编码,但可以完成。
    4. 我什至不愿提及这个选项,因为它是一个糟糕的选项,但为了全面披露,我想如果你认为它合适,你可以自行考虑它(但它绝对不是一个适用的架构几乎任何场景)。您可以使用 xp_cmdshell 调用命令行并为非关键任务执行 sqlcmd/osql - 此 sqlcmd 执行将与您正在执行的模块在单独的事务中,并且只需忽略 xp_cmdshell 故障应该允许主批处理继续。

    这些是一些想法......

    【讨论】:

    • 我考虑过使用第二个连接,带有单独的事务,有点像你的#4。我一直在寻找更好的解决方案,因为它需要访问未提交的主数据,并且如果主数据失败则需要手动清理,但这可能是最好的方法。感谢您的详细解答!
    【解决方案2】:

    您能否将您的导入到一个临时位置,仅对重要部分使用事务。加载临时位置后,吸收任何非关键错误后,您可以在单个事务中将数据复制到其最终目的地。取决于您所做工作的性质,但可能是一个可行的选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多