【发布时间】:2015-08-27 15:08:04
【问题描述】:
Java 也有同样的问题,但我对 .NET 的答案很感兴趣。
考虑以下代码:
class Program
{
static void Main()
{
try
{
RunTransaction();
// If there was an exception within the transaction,
// I won't be here anymore. But if the transaction was
// cancelled without an exception being thrown, I really
// need to know because I must stop here anyway.
OtherCode();
}
catch (Excexption ex)
{
// Log the exception...
// If an exception was thrown in the transaction scope,
// this must be logged here. If a "helper" exception was
// created in the Dispose method, this may be logged, but
// it won't say much. It just made sure that nothing else
// was executed in this try block.
}
}
static void RunTransaction()
{
using (var trans = new Transaction())
{
// An error may occur here and it should be logged.
throw new Exception();
// Maybe the scope is simply left without an exception.
return;
// Otherwise, the transaction is committed.
trans.Commit();
}
}
}
class Transaction : IDisposable
{
bool isCommitted;
public void Commit()
{
isCommitted = true;
}
public void Dispose()
{
if (!isCommitted)
{
// Was an exception thrown before this is called?
// If not, I might consider throwing one here.
// I can't always throw an exception here because if
// another exception is already propagated, it would
// be dropped and the real error cause would not be
// visible anymore.
}
}
}
在Transaction.Dispose方法中,如何知道是否已经抛出异常?
请注意,finally 块并未在此处显式显示,而是隐藏在调用IDisposable.Dispose 方法的using 语句中,此处显示。
更新:我的背景是我有一个事务包装类,其行为有点像TransactionScope。但是TransactionScope 太神奇了,不能按预期工作,所以我回到了真正的数据库事务。有些方法需要事务,但如果从另一个已经需要事务的方法调用它们,则内部“事务”必须“加入”外部事务,而不是从数据库请求新的嵌套事务,这在我的任何地方都不支持了解。实际代码比我的示例要复杂一些,其中内部事务可能会被取消,从而有效地结束事务。然后,如果任何东西继续在外部事务中运行,它不再存在,它就不能回滚,但会在任何事务之外有效地运行!必须采取一切手段防止这种情况发生。首先解决一个异常就可以了,但是如果没有这个,内部事务也可以被取消。这是我想在我的作用域助手类中检测到的。
【问题讨论】:
-
按 ctrl+alt+e 并标记 clr exception 复选框
-
如果你想知道交易是否被取消,为什么不从方法中获得一个返回值来表明它是否被取消?
-
您到底想达到什么目的?某种保护措施以确保没有代码从事务块返回而不提交?
-
我很难理解你想用这个做什么。如果发生异常,您可以在外部记录异常。你不应该把
Dispose()扔进去。我可能遗漏了一些东西,但这会给你带来什么?