是否可以在不支持分布式事务的情况下使用 System.Transactions 编程模型?
就像是
TransactionConfig.DisablePromotion = true;
不,您不能通过属性或配置禁用交易促销。禁用事务提升的唯一方法是避免导致事务提升为分布式事务的条件。
为避免事务管理升级,您需要:
使用 SQL Server 2005 或更高版本作为数据库
如果是 SQL Server 2005,则在事务的生命周期内仅使用一个数据库连接。(SQL Server 2008 将允许您在事务中使用多个连接而不会发生升级。)
只访问一个数据库
不跨应用程序域传递您的事务
制定规则的原因是为了确保事务的ACID 属性。
作为一个例子,让我们假设您可以指定不提升事务(如在您的代码片段中)但您的代码访问两个数据库(我知道 - 您的代码只使用一个数据库)。所以现在你已经指定不使用分布式事务,你已经启动了一个事务,并且你已经指定了两个数据库都应该在一个工作单元内。事务的 ACID 属性与避免分布式事务的愿望之间存在冲突。在我看来,有两种方法可以处理这个问题:要么将事务提升为分布式事务(你说你不想这样做!),要么抛出异常(因为你不能保证交易)。
因此,使用 DisablePromotion 属性不会有太大价值,因为应用程序要不促进事务,您仍然需要遵循升级规则。
如果你真的想要,你可以处理DistributedTransactionStarted事件并在分布式事务启动时抛出异常。这将保证您的应用程序没有使用分布式事务,但这可能不是您想要的。
我在禁用 MSDTC 服务的情况下使用以下代码。
var txOpts = new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadCommitted,
Timeout = TimeSpan.FromMinutes(10)};
using (var tx = new TransactionScope(TransactionScopeOption.Suppress, txOpts))
{
using (var db1 = new ObjectContext(connection1))
{
db1.Connection.Open();
using (var db1tx = db1.Connection.BeginTransaction(
System.Data.IsolationLevel.ReadCommitted))
{
using (var db2 = new ObjectContext(connection2))
{
db2.Connection.Open();
using (var db2tx = db2.Connection.BeginTransaction(
System.Data.IsolationLevel.ReadCommitted))
{
// do stuff
db1.SaveChanges(false);
db2.SaveChanges(false);
db1tx.Commit();
db2tx.Commit();
tx.Complete();
}
}
}
}
}