gpt4 book ai didi

c# - 交易升级为 DTC 无多重连接

转载 作者:行者123 更新时间:2023-11-30 18:32:50 25 4
gpt4 key购买 nike

有没有人知道在使用事务范围时在多个连接未打开时事务升级到 DTC 的情况。

我知道如果我在一个事务范围内打开多个连接(无论是什么连接字符串),该事务很可能会被提升到 DTC。

知道这一点后,我竭尽全力确保在我的交易中只打开一个连接。

但是,我有一个客户遇到异常

发生错误。 Csla.DataPortalException:DataPortal.Update 失败(基础提供者在打开时失败。) ---> Csla.Reflection.CallMethodException:EditableCategory.DataPortal_Update 方法调用失败 ---> System.Data.EntityException:基础提供者在打开时失败。 ---> System.Transactions.TransactionManagerCommunicationException:分布式事务管理器 (MSDTC) 的网络访问已被禁用。请使用组件服务管理工具在 MSDTC 的安全配置中为网络访问启用 DTC。 ---> System.Runtime.InteropServices.COMException: 事务管理器已禁用对远程/网络事务的支持。

同样,我很确定在该范围内只打开了一个连接。看一看。

 protected override void DataPortal_Update()
{
using (System.Transactions.TransactionScope ts = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, System.Transactions.TransactionManager.MaximumTimeout))
{
//get the dal manager he knows which dal implementation to use
using (var dalMgr = DataAccess.BusinessObjectsDalFactory.GetManager())
{
//get the category dal implementation
var ecDal = dalMgr.GetProvider<DataAccess.BusinessObjectDalInterfaces.ICategoryDAL>();

//assume all the data is good at this point so use bypassproperty checks
using (BypassPropertyChecks)
{
var catData = new Models.Category { CategoryId = CategoryId, CategoryName = CategoryName, LastChanged = TimeStamp };

ecDal.UpdateCategory(catData);

TimeStamp = catData.LastChanged;
}
}

ts.Complete();
}

base.DataPortal_Update();
}

public class DalManager : Core.Sebring.DataAccess.IBusinessObjectsDalManager {private static string _typeMask = typeof(DalManager).FullName.Replace("DalManager", @"{0}");

public T GetProvider<T>() where T : class
{
var typeName = string.Format(_typeMask, typeof(T).Name.Substring(1));
var type = Type.GetType(typeName);
if (type != null)
return Activator.CreateInstance(type) as T;
else
throw new NotImplementedException(typeName);
}

public Csla.Data.DbContextManager<DataContext> ConnectionManager { get; private set; }

public DalManager()
{
ConnectionManager = Csla.Data.DbContextManager<DataContext>.GetManager();
}

public void Dispose()
{
ConnectionManager.Dispose();
ConnectionManager = null;
}


public void UpdateDataBase()
{
DatabaseUpgrader.PerformUpgrade();
}
}

public void UpdateCategory(Models.Category catData)
{
if (catData == null) return;
using (var cntx = DbContextManager<DataContext>.GetManager())
{
var cat = cntx.DbContext.Set<Category>().FirstOrDefault(c => c.CategoryId == catData.CategoryId);

if (cat == null) return;

if (!cat.LastChanged.Matches(catData.LastChanged))
throw new ConcurrencyException(cat.GetType().ToString());

cat.CategoryName = catData.CategoryName;
//cntx.DbContext.ChangeTracker.DetectChanges();
cntx.DbContext.Entry<Category>(cat).State = System.Data.EntityState.Modified;
cntx.DbContext.SaveChanges();
catData.LastChanged = cat.LastChanged;
}

}

DBContextManager 的代码是可用的,但简而言之,它只是确保只有一个 DBContext,因此打开一个连接。我忽略了什么吗?我猜可能是 DBConextManager 出了问题,所以我也在 CSLA 论坛上发帖(DBContextManager 是 CSLA 的一部分)。但是有没有人遇到过确定在事务范围内打开一个连接并将事务升级到 DTC 的情况?

当然,我无法在我的本地开发机器或我们的任何 QA 机器上重现异常。

感谢任何帮助。

谢谢。

最佳答案

在使用 System.Transactions.TransactionScope 进行交易时, Entity Framework 可以随机尝试打开一个新连接

尝试添加一个 finally 语句并处理您的事务,同时调用您的 dbContext 并手动关闭连接,这将减少事务升级的次数,但它仍然可能发生:

finally
{
cntx.Database.Connection.Close();
transaction.Dispose();
}

这是一个已知的“错误”,您可以在此处找到更多信息:

http://petermeinl.wordpress.com/2011/03/13/avoiding-unwanted-escalation-to-distributed-transactions/

关于c# - 交易升级为 DTC 无多重连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18278994/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com