我正在寻找一种方法来继续执行事务,尽管在插入低优先级数据时出错。看起来真正的嵌套事务可能是一个解决方案,但SQL Server 2005/2008不支持它们。另一个解决方案是使用逻辑来判断错误是否是关键,但似乎也不可能。
以下是我的方案的更多细节:
使用ADO.NET/C#将数据周期性地插入到数据库中,虽然其中一些是至关重要的,但有些也可能没有问题而丢失。插入完成后,会对数据进行一些计算。 (重要的和非重要的)整个过程都在一个交易中,所以一切都保持同步。
目前,使用事务保存点,并对非重要插入期间发生的异常进行部分回滚。但是,这不适用于“批量中止”错误,它会自动回滚整个事务。我理解一些错误是至关重要的,但SQL Server认为失败的强制转换是批量中止错误。 (Info on batch errors)我试图阻止这些错误在低优先级数据上发生整个插入时降低。
如果我所描述的是不可能的,我愿意考虑任何替代方法来实现数据完整性,但允许非重要插入失败。
感谢您的帮助。
答案 0 :(得分:1)
不幸的是,无法按照您的描述完成(完全支持嵌套事务将是关键)。我能想到的几件事情在过去曾被用来解决这个问题:
最好的选择可能是将命令分成可以明确执行的重要/非重要命令,这自然会要求它们不依赖于顺序
还可以使用基于消息传递的方法(请参阅Service Broker),您可以在其中执行内联主命令,并将非主要命令推送到队列中以便稍后/单独执行。对队列的推送在批处理中是事务性的,但是当您弹出队列时执行命令将是独立的。这也要求他们不依赖于订单。
如果依赖于顺序,您可以对所有内容使用消息传递方法,这将确保顺序并且每个操作可以有单独的消息,然后将它们组合在一起(通过会话组)将允许您将它们从队列中拉出同样也为每种“类型”操作(即主要与非主要)使用单独的交易。如果所有分组的消息必须是一个自主操作,那么这需要一些特殊的编码,但是可以完成。
我甚至没有提到这个选项,因为这是一个可怕的选择,但是为了完全披露我认为如果你认为它适合你可以自行考虑它(但它绝对不是一个适用的架构几乎任何情况)。您可以使用xp_cmdshell调用命令行并为非关键任务执行sqlcmd / osql - 此sqlcmd执行将与您正在执行的模块处于单独的事务中,并且只是忽略xp_cmdshell失败应该允许主要批量继续。
这些是一些想法......
答案 1 :(得分:0)
您是否可以使用仅针对重要部分的交易进入临时位置。一旦加载了临时位置,吸收了任何非关键错误,您就可以在单个事务中将数据复制到其最终目标中。取决于你正在做的工作的性质,但可能是一个可行的选择。