LCJ*_*LCJ 1 c# msdtc transactions sql-server-2005 exception
我在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 = 0;
string currentBatchString = string.Empty;
int numberOfRecordsinBacth = 5000;
int sizeOfTheBatch = 0;
List<string> individualEntriesList = new List<string>();
string dataString = string.Empty;
if (dataStringToProcess != null)
{
dataString = dataStringToProcess.ToString();
}
individualEntriesList.AddRange(dataString.Split(new char[] { '|' }));
for (loopCounter = 0; loopCounter < individualEntriesList.Count; loopCounter++)
{
if (String.IsNullOrEmpty(currentBatchString))
{
currentBatchString = System.Convert.ToString(individualEntriesList[loopCounter]);
}
else
{
currentBatchString = currentBatchString+"|"+System.Convert.ToString(individualEntriesList[loopCounter]);
}
sizeOfTheBatch = sizeOfTheBatch + 1;
if (sizeOfTheBatch == numberOfRecordsinBacth)
{
batchDataStringList.Add(currentBatchString);
sizeOfTheBatch = 0;
currentBatchString = String.Empty;
}
}
return batchDataStringList;
}
private void PerformDatabaseOperation(string dataStringToProcess, int UserID)
{
SqlConnection mySqlConnection = new SqlConnection("data source=myServer;initial catalog=myDB; Integrated Security=SSPI; Connection Timeout=0");
SqlCommand mySqlCommand = new SqlCommand("aspInsertUSAZipCode", mySqlConnection);
mySqlCommand.CommandType = CommandType.StoredProcedure;
mySqlCommand.Parameters.Add("@DataRows", dataStringToProcess.ToString());
mySqlCommand.Parameters.Add("@currDate", DateTime.Now);
mySqlCommand.Parameters.Add("@userID", UserID);
mySqlCommand.Parameters.Add("@CountOfUnchangedZipCode", 1000);
mySqlCommand.CommandTimeout = 0;
mySqlConnection.Open();
int numberOfRows = mySqlCommand.ExecuteNonQuery();
}
Run Code Online (Sandbox Code Playgroud)
Dev Env:Visual Studion 2005
框架:.Net 3.0
DB:SQL Server 2005
当我运行查询SELECT [Size],Max_Size,Data_Space_Id,[File_Id],Type_Desc,[Name] FROM MyDB.sys.database_files WHERE data_space_id = 0 - 它说大小(日志)是128
更新 我们的应用程序中使用了三个不同的数据库.一个用于数据,一个用于历史记录,一个用于记录.当我在上面的连接字符串中放入enlist = false时,它暂时正常工作.但它在我的开发环境中.我怀疑它是否也适用于生产.有关潜在风险的任何想法?
谢谢
Lijo
当您在a中打开多个连接时TransactionScope,正在运行的事务将自动升级为分布式事务.要使分布式事务起作用,必须将SQL Server和运行应用程序的计算机上的MSDTC配置为允许网络访问.运行分布式事务时,SQL Server和本地DTC进行通信.
在您的情况下,问题很可能是运行您的应用程序的计算机上的MSDTC不允许网络访问,因为这是工作站的默认设置.要解决此问题,请执
系统可能会提示您重新启动DTC.UI中似乎存在错误,因为即使您接受重新启动DTC,也不会重新启动它.相反,您必须在服务管理器中手动重新启动DTC服务.
顺便说一句,记得在使用后关闭连接PerformDatabaseOperation.将它放在using块中是一种好习惯:
using (SqlConnection mySqlConnection = new .....)
{
// Some code here...
mySqlConnection.Open();
// Some more code ...
}
Run Code Online (Sandbox Code Playgroud)