SQL Server和Oracle的EF和TransactionScope没有升级/跨越到DTC?

时间:2013-08-28 13:26:28

标签: sql oracle entity-framework transactions transactionscope

任何人都可以就此主题向我提问吗?

我想在我的应用程序中同时支持SQL Server和Oracle。

是否可以让以下代码(在BL中)同时适用于SQL Server和Oracle而不会升级/跨越到分布式事务(DTC)?

 // dbcontext is created before, same dbcontext will be used by both repositories
 using (var ts = new TransactionScope())
 {
    // create order - make use of dbcontext, possibly to call SaveChanges here
    orderRepository.CreateOrder(order);

    // update inventory - make use of same dbcontext, possibly to call SaveChanges here
    inventoryRepository.UpdateInventory(inventory);

    ts.Complete();
 }

截至今天,2013年8月底,据我所知,它适用于SQL Server 2008+ ...但是Oracle呢?我发现这个thread ...看起来甲骨文正在推广分布式交易,但我仍然不清楚。

有没有人有编写应用程序的经验,以支持SQL Server和带有Entity Framework的Oracle来启发我?

谢谢!

更新:最后我注意到EF6附带了Improved Transaction Support。除了Remus的推荐之外,这可能是我的解决方案。

2 个答案:

答案 0 :(得分:1)

Nope,分布式事务需要DTC - 跨越这样的2种不同数据库技术的东西是分布式事务。遗憾!

答案 1 :(得分:1)

首先:永远不要使用var ts = new TransactionScope()。是一个杀死你的应用程序的班轮。始终使用允许您指定隔离级别的显式构造函数。请参阅using new TransactionScope() Considered Harmful

现在关于你的问题:不将同一范围内的两个连接提升到DTC的逻辑很大程度上依赖于合作的驱动程序/提供程序通知System.Transactions两个不同的连接能够正确管理分布式事务他们自己因为涉及的资源管理者是一样的。 SQL Server 2008之后的SqlClient是一个能够执行此逻辑的驱动程序。您使用的Oracle驱动程序不是(我不知道任何版本,顺便说一句)。

最终真的非常基本:如果你不想要DTC,不要创建一个!确保在范围中使用一个连接。很明显,你不需要两个连接。换句话说,摆脱数据模型中的两个单独的存储库。只使用一个存储库来存储订单,库存以及其他什么不存在。你正在与他们一起射击自己,并且你正在寻找精灵粉尘解决方案。

更新:Oracle driver 12c r1

  

“事务和连接关联:默认情况下,ODP.NET连接仅在关闭连接对象或处理事务对象时才从事务中分离”