Sam*_*dam 25 .net c# transactionscope
假设我有一个连接到n数据库的Windows窗体应用程序,n同时打开连接.
我正在寻找的是一次性与所有这些数据库进行交易.
例如,如果我有2个数据库连接:
using (ITransaction tx1 = session1.OpenTransaction())
{
using (ITransaction tx2 = session2.OpenTransaction())
{
// Do the query thingy here
}
}
Run Code Online (Sandbox Code Playgroud)
写一切都很好,但是当我想在这里和那里查询时,事情变得多余,更不用说添加新连接的可能性了.
我想要的是循环所有已注册的会话并将其包装在服务中,可能是这样的:
class TransactionManager
{
private ISession[] _sessions;
public TransactionManager(string[] connectionStrings)
{
// Initialize the sessions here
}
public function DoTransaction(string query)
{
foreach (ISession session in _sessions)
{
// What to do here? Using? Try-catch?
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在foreach循环中使用use ,则意味着如果连接A成功但连接B不成功,那么只有连接B将被回滚.
Stu*_*tLC 40
看来你可能正在重新发明TransactionScope.在一个工作单元下完成所有这些工作非常简单*:
using (TransactionScope scope = new TransactionScope())
{
... Do Stuff with Connection 1 using SqlDataReader
... Do Stuff with Connection 2 using Entity Framework
... Do Stuff with Connection 3 on another Oracle Database
... And for good measure do some stuff in MSMQ or other DTC resource
scope.Complete(); // If you are happy
}
Run Code Online (Sandbox Code Playgroud)
Stuff不需要内联 - 它可以在不同的类或不同的程序集中.如果您使用的资源能够登记到环境事务中,则无需显式注册数据库或队列连接TransactionScope- 一切都会发生.automagically
现在小字体:
*每当您同时使用多个数据库连接,或不同的连接字符串或多种技术时,这将需要2阶段提交并升级到DTC事务,以确保跨资源的ACID.DTC本身具有更多的小字体,并且在企业网络中提出了更多挑战,例如防火墙,集群,安全配置和错误.但是,对于MS Sql Server上的轻量级事务,如果可以使用相同的数据库和相同的连接字符串设置保持所有连接,并在打开下一个连接之前关闭每个连接,则可以避免DTC.
在提交或回滚事务之前,维护跨多个ACID资源的事务将始终保持对这些资源的锁定.这通常不会在大批量企业中实现良好的睦邻关系,因此请务必考虑锁定的后果.
如果Stuff跨多个线程完成,则需要依赖DependentTransaction
值得一提的最后一点是使用TransactionScopeSerializable 的默认隔离级别,它容易出现死锁.在大多数非关键场景中,您可能会将其降低到Read Committed.
使用TransactionScope,它将负责提交或回滚所有包含的事务:
using (var ts = new TransactionScope())
{
... // your old code
ts.Complete()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19358 次 |
| 最近记录: |