2010-03-08 91 views
4

有人能告诉我TransactionScope如何保证跨多个数据库的数据完整性的原则吗?我想它首先将命令发送到数据库,然后等待数据库响应,然后向它们发送消息以应用先前发送的命令。但是,当发送这些应用消息时突然停止执行时,我们仍然可能会得到一个应用该命令的数据库和一个没有应用该命令的数据库。任何人都可以对此有所了解吗?TransactionScope如何保证跨多个数据库的数据完整性?

编辑:

我想林问的是什么,我可以依靠的TransactionScope在停电或突然停机的情况下写入多个数据库时,以保证数据的完整性。

谢谢,巴斯

实施例:

using(var scope=new TransactionScope()) 
    { 
     using (var context = new FirstEntities()) 
     { 
      context.AddToSomethingSet(new Something()); 
      context.SaveChanges(); 
     } 

     using (var context = new SecondEntities()) 
     { 
      context.AddToSomethingElseSet(new SomethingElse()); 
      context.SaveChanges(); 
     } 

     scope.Complete(); 
    } 
+0

顺便说一句,你正在你的代码中进行序列化的隔离事务。 – Henrik 2012-01-20 09:25:30

回答

2

对于分布式事务,实际上可能会发生数据库变得不一致的情况。你说:

在某些时候,两个数据库都必须 被告知应用其更改。让 说有 告诉第一个数据库应用,然后 数据库不同步后有一个停电。还是我 错过了什么?

你不是。我认为这被称为将军问题。它可以被证明是不可预防的。然而,失败的窗口非常小。

+0

就我了解维基百科关于将军问题的文章而言,假设一条消息及其确认已成功交换(又名tx-log中编写的任意步骤),2PC可避免不一致。如果你的网络在一个提交后出现故障,另一个尚未提交,那么第一个将成功准备,另一个(否则它们将不会被告知提交),第一个数据库可以安全地承担第二个数据库在它重新联机时将会提交。 – Henrik 2010-03-26 11:07:58

+0

只有当您认为只有有限的信息可能会丢失时,才会出现此情况。如果所有的信息在最坏的时候都可能丢失,你仍然会失去信心。 – usr 2011-02-08 22:53:36

6

它,如果它检测到它使用每个范围作为2相的一部分提交多个数据库提升到分布式事务协调器(MSDTC)。 Each scope votes to commit,因此我们得到了ACID属性,但分布在数据库中。它也可以与TxF,TxR集成。你应该能够以你描述的方式使用它。

这两个数据库是一致的,因为在MTC下运行的分布式COM +事务已附加到它们的数据库事务中。

如果一个数据库投票(例如通过执行(:TransactionScope).Commit()),“it”会告诉DTC它投票提交。当所有的数据库都完成后,他们有一个更改列表。至于数据库事务现在不会发生死锁或与其他事务冲突(例如,通过预先占用一个事务的公平算法),每个数据库的所有操作都在事务日志中。如果在还没有提交一个数据库时已经完成了对另一个数据库的提交时系统断电,那么已经在事务日志中记录了所有资源都已投票提交的情况,因此不存在提交失败的逻辑暗示。因此,下一次无法启动的数据库启动时,它将完成处于这个不确定状态的事务。

+0

感谢您的回答,但我仍然有点困惑。在某些时候,两个数据库都必须被告知应用其更改。假设在告诉第一个数据库应用后出现停电,那么数据库不同步。或者我错过了什么? – 2010-03-08 12:26:28

+0

我的意思是单独的两个数据库都是有效的,但它们不再彼此同步。 – 2010-03-08 12:27:54

+0

我在回答中添加了更多内容。请参阅维基百科链接了解更多链接和资源。简而言之;它可以在数据库不同步的情况下工作(它们也在内部使用2PC),如果你使用TransactionScopes,那么你应该没有什么可担心的。尽管如此,还有更多的细节可以应用到这个答案中,例如磁盘写入实际上并不是与数据库系统假设相反的原子,以及您应该使用哪种类型的硬盘驱动器以便尽可能多地访问(http:/ /forums.bit-tech.net/showthread.php?t=146156) – Henrik 2010-03-08 13:16:02