我想确认实体框架的ObjectContext.Connection.BeginTransaction()方法返回的事务是否使用MSDTC(Microsoft分布式事务处理协调器)的支持?
有没有办法在没有MSDTC支持的情况下使用交易?
msdtc entity-framework transactions distributed-transactions objectcontext
我有一个应用程序保存到数据库(使用实体框架)并在单个保存中将文档保存到Sharepoint.我正在尝试将MSDTC与TransactionScope一起使用.
我的EF插入逻辑的一部分包括将外键列表传递给数据层.该层从db中检索"foreign key'd"对象,然后将其添加到主对象.奇怪的是,这适用于第一个外键项目,但在第二个时出现以下消息失败.
System.Data.EntityException:基础提供程序在Open上失败.---> System.Transactions.TransactionManagerCommunicationException:已禁用分布式事务管理器(MSDTC)的网络访问.请使用组件服务管理工具在MSDTC的安全配置中启用DTC以进行网络访问.
MSDTC已启用并在第一次通过期间工作,但不是第二次通过.我假设当我进行几个选择调用时,上下文会以某种方式混淆?
这是我的逻辑:
//Create new order
foreach(int lineItemId in lineItems)
{
//Retrieve the LineItem object from db
//Add the LineItem object to the Order
}
//Save using EF
Run Code Online (Sandbox Code Playgroud)
也许我不应该从数据库中检索对象?我错过了在EF中引用关系的简单方法吗?
我有一个具有自托管WCF服务的解决方案.该服务连接到EF,可以读写.
在同一解决方案中,我还托管了一个NServiceBus端点.它从单独的运行解决方案中获取事件.
当我运行NServiceBus项目(单独)时,似乎工作正常,直到我尝试查询我的数据库.当我这样做时,我得到这个EntityException:
底层提供程序在Open上失败.
内部异常是TransactionException,消息为:
合作伙伴事务管理器已禁用其对远程/网络事务的支持
我的NServiceBus和WCF服务项目都使用完全相同的配置和EF项目.我不明白为什么一个失败而另一个失败.
我做了一些谷歌搜索并遇到了这个页面:http://msdn.microsoft.com/en-us/library/aa561924%28BTS.20%29.aspx向我展示了如何设置MSDTC,我在我的客户端上做到了机.但它没有效果.
我还发现这个问题需要设置:NServiceBus:System.Transactions.TransactionException:合作伙伴事务管理器已禁用其对远程/网络事务的支持.但它没有说明为什么或在哪里.
我是否需要在数据库服务器上设置MSDTC?如果是这样,为什么?什么是MSDTC?
为什么从NServiceBus托管进程运行会导致此错误?
更新:我发现这个链接帮助我了解DTC的作用.它还告诉我如何在需要时将其关闭:
using (TransactionScope sc=new TransactionScope(TransactionScopeOption.Suppress))
YourDatabaseHandler.SaveMyStuff(whatever);
Run Code Online (Sandbox Code Playgroud)
虽然在许多情况下听起来好像是好事.
在我们的生产环境中,我们有一个存储过程(在sql 2005服务器中),它将数据从远程存储过程(存储在远程sql 2008中)导入到本地表中.
代码是这样的:
insert <<local table name>> (fund, strat, clr, [id], position, unsettledPosition)
exec <<remote stored proc name>> 'aapl us' , '2013-05-13'
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
无法在分布式事务中使用SAVE TRANSACTION.
和
当前事务无法提交,也无法支持写入日志文件的操作.回滚交易.
我已经配置了本地和远程DTC,允许通过网络进行DTC访问,允许远程客户端选项,还允许入站和出站通信,最后启用XA事务,但没有任何成功.
直到昨天,远程服务器是一个旧的SQL 2005,我的代码运行良好,然后我想我错过了新服务器2008中的一些配置设置.
请有人帮帮我吗?
我有2个链接的SQL服务器,两者都是SQL Server 2012 Express Edition.我正在将insert语句执行到连接的SQL Server表中,直到现在它才能完美运行.我什么都没改变.但现在它给了我以下错误信息.
服务器'MSERVER1-PC\SQLEXPRESS'上的MSDTC不可用.
我启用了"分布式事务处理协调器"服务.尝试重新启动它并尝试了所有选项,但都是静脉.在分布式事务处理协调器下的组件服务中,在本地DTC中,我启用了网络DTC访问.允许入站和允许出站.检查网络DTC访问.几乎所有人都尝试了但都是静脉.
任何的想法...
交易范围如何运作?它是如何知道何时已经使用了另一个上下文,以及如何在我的代码中实现另一种范围.
我主要是一个vb.net开发人员,但如果你写的话,我可以阅读c#.
如果上述情况过于模糊:
我理解system.transactions的作用以及如何使用它.我想知道的是如何创建类似的东西,我自己的库,我可以包装一些代码,可以像system.transactions范围一样处理它.我打算在缓存模型中使用它,它会大大增强它.我正在寻找有关事务范围如何知道的详细信息,例如存在父范围,因此它可以附加到它等等,或者提交然后需要在更高级别或更高级别的联系中进行.
例如,如果我有以下内容
using scope1 as new system.transactions.scope
using scope2 as new system.transactions.scope
using scope3 as new system.transactions.scope
scope3.commit
end using
scope2.commit
end using
end using
Run Code Online (Sandbox Code Playgroud)
Scope1不会提交,因此scope2或scope3也不会提交,因为它们的父级都是scope1的上下文.我希望能够用我自己的库来设置它.
我在C#应用程序的事务中获得MSDTC异常.该功能是在从csv文件读取后将十万(十万)个zipcode记录上载到数据库表中.此操作在大约20个批处理数据库操作中完成(每个批处理包含5000个记录).如果我不使用事务,功能正常.
有趣的是,使用交易的其他功能可以完成交易.这导致我假设异常消息是误导性的.
关于可能出现什么问题的任何想法?
例外:"已禁用分布式事务管理器(MSDTC)的网络访问.请使用组件服务管理工具在MSDTC的安全配置中启用DTC以进行网络访问."
来源:System.Transactions
内部异常:"事务管理器已禁用其对远程/网络事务的支持.(HRESULT异常:0x8004D024)"
注意:事务中有一个for循环.它引起了任何问题吗?
实际要求是:zipcode表中有一些现有的zipcodes.管理员每个月都会上传新的zipcode csv文件.来自csv的新项目已插入.csv中不可用的邮政编码(但存在于数据库中)被视为已停用且将被删除.退役邮政编码列表将返回到用户界面.新添加的邮政编码也需要退回.
private void ProcessZipCodes(StringBuilder dataStringToProcess, int UserID)
{
int CountOfUnchangedZipCode = 0;
string strRetiredZipCode = "";
string strNewZipCode = "";
dataStringToProcess.Remove(dataStringToProcess.Length - 1, 1);
if (dataStringToProcess.Length > 0)
{
List<string> batchDataStringList = GetDataStringInBatches(dataStringToProcess);
//TimeSpan.FromMinutes(0) - to make transaction scope as infinite.
using (TransactionScope transaction = TransactionScopeFactory.GetTransactionScope(TimeSpan.FromMinutes(0)))
{
foreach (string dataString in batchDataStringList)
{
PerformDatabaseOperation(dataString, UserID);
}
transaction.Complete();
}
}
}
private List<string> GetDataStringInBatches(StringBuilder dataStringToProcess)
{
List<string> batchDataStringList = new List<string>();
int loopCounter …Run Code Online (Sandbox Code Playgroud) lock (_connectionLock) {
if (conn == null) {
conn = GetOpenConnection(connectionString);
}
try {
PerformDbAction(conn);
} finally {
conn.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
我遇到了一个问题,多线程可能导致空连接问题,因为它们可以被一次运行的多个线程打开和关闭.我试图通过锁定进程解决问题(上面,为了清晰起见简化了代码),但发现这严重降低了性能.
我尝试通过使用两个单独的锁来创建/处理数据库连接并在锁定之外执行数据库操作来解决此问题:
lock (_connectionLock) {
if (conn == null) {
conn = GetOpenConnection(connectionString);
}
}
try {
PerformDbAction(conn);
} finally {
lock(_connectionLock)
conn.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
只有我意识到上述不起作用,因为另一个线程可能尝试使用已由另一个线程处置的连接执行数据库操作.
任何人都可以建议一个替代方案或解决方案,我可以安全地锁定对数据库连接字符串的访问,而不会减慢一切这么多?
编辑:很抱歉之前不包括这个,但我不仅仅是创建新连接并立即处理它们的原因是我试图避免不必要的MSDTC升级.在使用GetOpenConnection时,我正在重用现有连接,因为这是触发MSDTC升级的事情之一.
我已设法避免使用顶级代码示例进行升级,但执行速度太慢.
有没有人对如何在当前机器上读取MSDTC配置有任何想法?我特意试图检查用户是否已执行以下步骤:
打开组件管理(开始>所有程序>管理工具>组件服务)
双击"组件服务",然后展开"计算机".右键单击"我的电脑",然后选择"属性"
在MSDTC选项卡上,单击"安全配置"按钮,然后按如下方式配置属性:
网络DTC访问:已检查
允许远程客户端:已选中
允许入站:已选中
允许出站:已检查
需要传入呼叫者身份验证:已选中
它是我需要编写的一个小组件的一部分,用于验证最终用户配置.如果错误的话,我认为我不会尝试修复它:只需将用户指向帮助文件 - 因此只需要只读.
msdtc ×9
c# ×3
transactions ×3
sql-server ×2
.net ×1
exception ×1
locking ×1
nservicebus ×1
sql ×1