我在C#應用程序的交易中遇到了MSDTC異常。其功能是在從csv文件讀取數據後,上傳一個十萬條(十萬條)的郵政編碼記錄到數據庫表中。該操作在大約20個批量數據庫操作中完成(每個批次包含5000個記錄)。如果我不使用事務,那麼功能工作正常。在交易過程中的MSDTC異常:C#
有趣的部分是,使用交易的其他功能能夠完成他們的交易。這導致我認爲異常信息是一種誤導性的假設。
有什麼想法可能是什麼問題?
例外:「分佈式事務管理器(MSDTC)的網絡訪問已被禁用。請啓用DTC使用組件服務管理工具在安全配置網絡接入的MSDTC。」
來源:System.Transactions的
內部異常:「事務管理器已禁用其遠程/網絡事務的支持。 (來自HRESULT的異常:0x8004D024)「
注意:事務內部有一個for循環。它是否導致任何問題?
實際要求是:郵編表中有一些現有的郵編。管理員每個月都會上傳新的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();
}
開發ENV:視覺Studion 2005
框架:NET 3.0
DB:SQL Server 2005中
當我運行查詢SELECT [尺寸],MAX_SIZE,Data_Space_Id,[ File_Id],Type_Desc,[Name] FROM MyDB.sys.database_files WHERE data_space_id = 0 - 它表示(日誌)的大小爲128
UPDATE 我們在應用程序中使用了三種不同的數據庫。一個用於數據,一個用於歷史記錄,另一個用於記錄。當我把enlist = false放在上面的連接字符串中時,它現在正在工作。但它在我的開發環境中。我懷疑它是否也能用於生產。任何關於潛在風險的想法?
感謝
Lijo
實際要求是:在zipcode表中有一些現有的zipcode。管理員每個月都會上傳新的zipcode csv文件。插入來自csv的新項目。在csv中不可用的郵政編碼(但存在於數據庫中)被認爲是退役並將被刪除。已退役的郵政編碼列表將被退回到用戶界面。新增加的郵政編碼也需要退回。 使用SqlBulkCopy可以實現這個功能嗎?你可以請參考一個很好的例子嗎? – Lijo
我們在應用程序中使用了三種不同的數據庫。一個用於數據,一個用於歷史記錄,另一個用於記錄。 當我將enlist = false放入連接字符串中時,它暫時工作。但它在我的開發環境中。我懷疑它是否也能用於生產。任何關於潛在風險的想法? – Lijo
如果您正在跨數據庫進行事務處理,那麼您正在執行分佈式事務。如果數據庫位於不同的機器上,並且您希望在事務內完成這項工作,則需要爲遠程事務配置MSDTC。或者,您自己的應用程序可以建立三個連接(每個數據庫一個連接)。在這種情況下,您將通過應用程序在數據庫之間傳遞數據並管理三種不同的事務。配置MSDTC有這樣的問題嗎? –