我们是否因为例外而最终确定?

时间:2018-04-20 16:51:26

标签: c# .net-core

我在.NET 4.7中有一个工作单元实现,它正在检查在处理期间是否发生了异常。如果有,则调用事务上的回滚。它没有捕获异常,或试图处理它,它只是试图确保在发生异常时发生回滚。

正在使用;

Marshal.GetExceptionPointers() != IntPtr.Zero && Marshal.GetExceptionCode() != 0

我需要将此代码移植到.NET Core 2.1。但是GetExceptionPointers()不再存在,并且GetExceptionCode被标记为已过时,没有任何替代它的指示。我不太确定如何定义我正在寻找的东西,但我需要等效的行为,所以我可以移植这段代码。有什么想法吗?

要扩展这一点。这是围绕EF DbContext的单元工作实现。它目前运行良好,如果发生异常,则成功回滚对数据库的任何更改。它内部不能有try / catch,因为它是这样使用的;

using(var uow = ctx.Begin())
{
.. code 
}

我不是试图处理这里的异常,我试图在异常发生时回滚事务。这似乎是一种糟糕的做法,我有兴趣学习替代方案,但我必须有相同的行为。

1 个答案:

答案 0 :(得分:0)

这里的答案是改变代码设计的整个方式。我不能深入研究,因为这不是个人项目,但这就是我正在寻找的原因以及我们提出的解决方案。

该系统旨在制作可从其他组件调用的可重用组件。从而;

A can invoke B which can invoke C
D can invoke C
C can be invoked on its own

这个想法是将系统分解成更小的部分。它足够小,不能保证被放入像NServiceBus或MT这样的更分散的系统中。

当我们这样做时,整个事情应该包含在一个事务(或工作单元)中,这样就可以独立地处理独立的代码片段,但如果一个片段失败则它们都会回滚。由于这种设计,我们不能像大多数例子那样处理DbContext,它就是工作单元。

因此,正如评论中所建议的那样,我们唯一的解决方案是在某个地方放置一个try..catch。我们有一个调用这些部分的类,因此我们将其更改为开始环境事务并了解是否嵌套了一个部分。如果发生异常,它将处理事务而不完成并冒泡,因此,如上例所示,B中的错误将导致在C和A中完成的任何操作进行回滚。

我意识到原始代码写入的时刻是黑客攻击,但它确实为我们提供了日常优雅的解决方案。这只是迫使我们重新审视设计。