2009-11-11 65 views
0

我正在寻找一种方法来在插入低优先级数据时继续执行事务,尽管存在错误。似乎真正的嵌套事务可能是一个解决方案,但它们不受SQL Server 2005/2008的支持。另一个解决方案是通过逻辑来判断错误是否严重,但看起来这也是不可能的。从事务中的SQL批处理中止错误中恢复?另类?

这里有我的方案更加详细:

数据使用ADO.NET/C#数据库periodicaly插入,而一些它是至关重要的,有的还可能会丢失没有问题。插入完成后,会对数据进行一些计算。 (无论是重要的还是非重要的)整个过程都在交易中,因此一切都保持同步。

当前使用事务保存点,并且对非重要插入过程中发生的异常进行部分回滚。但是,这不适用于“批次中止”错误,它会自动回滚整个事务。我知道一些错误至关重要,但SQL Server认为失败的转换类型是批处理中止错误。 (Info on batch errors)我试图防止这些错误,如果它们发生在低优先级数据上,则会导致整个插入错误。

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

感谢您的帮助。

回答

1

不幸的是,不能像你描述的那样完成(完全支持嵌套事务将会是关键)。两件事情我可以认为已经被用来解决这个问题,在过去:

  1. 最好的办法可能是命令分成可能被清楚地执行的重要/非重要的命令,当然,这会要求它们不相互依赖于订单

  2. 也可以使用基于消息传递的方法(请参阅Service Broker),您将在其中执行内联主要命令并将非主要命令推送到队列以供稍后/单独执行。推入队列将在批处理中是事务性的,但是当您退出队列时执行该命令将是分开的。这也会要求它们不是相互依赖的订单。

  3. 如果依赖于订单,您可以使用消息传递方法处理所有事情,这样可以确保顺序并可以为每个操作分别发送消息,然后将它们组合在一起(通过会话组)将允许您将它们从队列中拉出并且为每种“操作类型”(即主要与非主要)使用不同的交易。如果所有分组消息都必须是单独的自主操作,但是可以完成,那么这将需要您的一些特殊编码。

  4. 我很犹豫甚至提到这个选项,因为这是一个糟糕的选择,但为了充分披露,我认为如果您认为它适合,您可以酌情考虑它(但它绝对不是一种适用于几乎任何场景)。您可以使用xp_cmdshell调用命令行并为非关键任务执行sqlcmd/osql - 此sqlcmd执行将与您正在执行的模块处于单独的事务中,并且仅仅忽略xp_cmdshell失败应允许主批量继续。

这些是一些想法...

+0

我曾考虑过使用第二个连接,并使用单独的事务处理,这有点沿着#4的路线。我一直在寻找更好的解决方案,因为它需要访问未提交的主数据,并且如果主数据失败需要手动清理,但它可能只是最好的方法。感谢您的详细解答! – Djof 2009-11-12 14:54:59

0

您能否将您的进口导入临时位置,仅对重要部分使用交易。一旦加载了临时位置,吸收了任何非严重错误,您就可以在单次事务中将数据复制到其最终目标中。取决于你所从事的工作的性质,但可能是一个可行的选择。