在過去的幾天裏,我一直在毆打我的頭靠在牆上,我似乎無法想出一個好的解決方案。WCF服務導致SQL死鎖錯誤
我有一個WCF服務,充當我們所有數據庫交互的唯一入口點。在目前的困境中,有一種Windows服務針對Microsoft Dynamics CRM中的「AsyncOperation」表進行調整。無論何時在CRM中創建實體記錄,Windows服務都會將記錄從AsyncOperation表中提取出來,並使用該數據將請求發送到WCF服務。我遇到的問題是,當該Windows服務同時向WCF服務發出多個請求時,該服務會導致SQL中的事務死鎖。
我向WCF服務中的數據流添加了一些額外的日誌記錄,並且我發現在任何給定時間3到5個請求中的任何一個都可能在幾毫秒內觸擊服務。看來,在這個過程中擊中該服務的第一個要求就是把它做成了數據庫的唯一一個,其餘最終導致一個SQL死鎖錯誤:
Transaction (Process ID 95) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
我的問題是:是否有一個良好實現排隊過程的一些時間或單一方法到WCF,這將確保SQL插入不會在同一時間發生?由於我在MS Dynamics平臺之上構建,所以我沒有辦法確保多個請求不能同時處理。輸入到系統中的數據是由外部合作伙伴提供的,其中一些數據相當沉重。
我接受任何建議,我可以尋找解決方案。
在處理插入WCF服務的方法是這樣的:
public List<NoelGroup.Users.Core.Entity.BusinessLayer.PersonEntity> Insert(NoelGroup.Users.Core.Entity.BusinessLayer.PersonEntity businessObject)
{
List<NoelGroup.Users.Core.Entity.BusinessLayer.PersonEntity> businessObjectList = null;
using (SqlConnection conn = MainConnection)
{
int id = new Random().Next(9999);
try
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("[crud].[usp_Person_InsertUpdate]", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@iui_PersonId", businessObject.PersonId));
cmd.Parameters.Add(new SqlParameter("@ii_PrefixId", businessObject.PrefixId));
cmd.Parameters.Add(new SqlParameter("@ivn_FirstName", businessObject.FirstName));
cmd.Parameters.Add(new SqlParameter("@ivn_MiddleName", businessObject.MiddleName));
cmd.Parameters.Add(new SqlParameter("@ivn_LastName", businessObject.LastName));
cmd.Parameters.Add(new SqlParameter("@ic_Gender", businessObject.Gender));
cmd.Parameters.Add(new SqlParameter("@ii_SuffixId", businessObject.SuffixId));
cmd.Parameters.Add(new SqlParameter("@ii_PersonTypeId", businessObject.PersonTypeId));
cmd.Parameters.Add(new SqlParameter("@id_BirthDate", businessObject.BirthDate));
cmd.Parameters.Add(new SqlParameter("@iti_PreferredContactMethodId", businessObject.PreferredContactMethodId));
cmd.Parameters.Add(new SqlParameter("@iv_ModifiedUsername", businessObject.ModifiedUsername));
Logger.Log(string.Format("-- PersonEntity Insert ({1}) Execute -- {0}", DateTime.Now, id));
using (SqlDataReader rdr = cmd.ExecuteReader())
{
businessObject = null;
businessObject = new NoelGroup.Users.Core.Entity.BusinessLayer.PersonEntity();
businessObjectList = PopulateObjectsFromReader(rdr);
}
Logger.Log(string.Format("-- PersonEntity Insert ({1}) Complete -- {0}", DateTime.Now, id));
}
}
catch(Exception ex)
{
throw new SeverityException(500, string.Format("PersonEntity::Insert ({0})::Error occured.", id), ex);
//throw new SeverityException(500, "PersonEntity::Insert::Error occured.", ex);
}
}
return businessObjectList;
}
是您的WCF服務的負載平衡呢? – Daryl 2013-02-28 16:04:23
最初它本來就是通過代理通過WSO2 esb的本質。但是我們遇到了ESB上的一些網絡流量問題,所以我們推遲了這個實施。截至目前,只有海峽呼叫WCF服務。 – keannan5390 2013-02-28 16:12:49