我有一个UnitOfWork类,它根据块中的错误提交或回滚事务。
class UnitOfWork: IDispose
{
public void Dispose()
{
if (Marshal.GetExceptionCode() == 0
|| Marshal.GetExceptionPointers() == IntPtr.Zero)
{
// Commit
}
else
{
// Rollback
}
}
}
}
此类以下列方式使用:
try
{
using (var uow = new UnitOfWork())
{
// Do something here that causes an exception
}
}
catch
{
using (var uow = new UnitOfWork())
{
// Log exception
}
}
我已经阅读了这篇文章: Detecting a Dispose() from an exception inside using block
在上面的问题中,Steven(其中一位回复的人)提到,如果我在Dispose()中为“try”部分中的“using”块检测到异常,我就无法创建另一个UnitOfWork类。 “catch”阻塞并将错误记录到数据库中(因为Dispose()中的“Marshal”代码将继续说有异常),这意味着ExceptionCode和ExceptionPointers将从try块“浮动”(?)到catch块。
然而,在我的情况下,这是正常的 - 即。如果“try”部分的“using(var uow = new UOW)”块中有异常,它会正确捕获异常,然后在catch块中传递“if”条件,导致提交发生并允许我记录异常。
归结为我对Marshal.GetExceptionPointers()的工作原理有不完全的理解。有人可以确认我的使用模式是否正常工作(到目前为止所有测试似乎都表明它正常工作)以及Marshal.GetExceptionPointers()究竟在做什么?
答案 0 :(得分:1)
IDisposable.Dispose
旨在释放资源,将提交/回滚操作放入其中是一个坏主意。调用者应该知道如何处理异常以及如何回滚。
using (var unitOfWork = new UnitOfWork())
{
try
{
Prepare();
Step1();
Step2();
unitOfWork.Commit();
}
catch(PrepareException e)
{
//no necessary to rollback, just log it
}
catch(FirstStepException e1)
{
//rollback step1
}
catch(SecondStepException e2)
{
//rollback step1 and step2
}
}