纯C#编码中的事务
我想知道是否有一种简单的方式来处理C#中的某种事务。假设我们有两个属性,我们想更新它们的值。我们可以写:纯C#编码中的事务,c#,.net,C#,.net,我想知道是否有一种简单的方式来处理C#中的某种事务。假设我们有两个属性,我们想更新它们的值。我们可以写: A = GetA(); B = GetB(); 问题是,如果在分配B时抛出异常,则对象将处于不一致状态,因为A已更新。我们可以通过存储A的当前值并在处理B时捕获异常来解决此问题: var tempA = A; A = GetA(); // A is up to date try { B = GetB(); } catch { A = tempA; } // B is up to date
A = GetA();
B = GetB();
问题是,如果在分配B时抛出异常,则对象将处于不一致状态,因为A已更新。我们可以通过存储A的当前值并在处理B时捕获异常来解决此问题:
var tempA = A;
A = GetA(); // A is up to date
try { B = GetB(); } catch { A = tempA; } // B is up to date also or A is reverted
即使是上述解决方案也无法保存,因为在还原时可以引发异常,但问题是,.NET中是否存在简化此类操作的内置机制
我可以想象这样一种说法:
transaction { A = GetA(); B = GetB(); }
或代码构造,如:
Transaction.Enter();
A = GetA();
B = GetB();
Transaction.Leave();
在事务之前,将存储机器状态,事务之后,如果出现异常,将恢复机器状态。在.NET中有类似的东西吗?您可以使用TransactionScope类 例如:
using(var scope = new TransactionScope())
{
DoAction1();
DoAction2();
scope.Complete();
}
对象事务没有内置功能。但是有一些第三方库提供此功能以支持对象状态管理 你可以看看这个类似的问题 “TransactionScope不仅仅用于数据库。实现IEnlistmentNotification接口的每个组件都可以参与事务范围的两阶段提交 以下是事务性内存存储的示例: " 资料来源:
我认为您可以实现这个
IEnlistmentNotification
接口并使用TransactionScope
?tempA=GetA();B=GetB();A=tempA
?@A=tempA maight抛出异常,因为我们不知道setter是如何实现的。我们不关心A的setter是如何实现的。它记录了在某些情况下抛出异常……或者不抛出异常。异常并不是突然出现的神奇事物(线程中止除外)。他们是错误,如果二传手失败,意味着我们可以事先检查出一些错误。@cHao即使我们知道他们可以抛出异常,我们有时也无法预测它何时发生。它可能取决于网络连接或时间。因此,我们尝试分配一个属性,但无法确定是否成功。是否需要scope.complete()
?似乎与using
语句的概念相反。您需要将事务标记为已完成,然后在“using”结束时将其处置,以便提交事务。如果您不将其标记为已完成,它将在“using”范围结束时回滚。