[英]Error - LINQ/TransactionScope with multiple database connections
我有一個helluva時間將幾個事務包裝到同一個SQL Server上的兩個不同的數據庫。 我最初遇到網絡DTC訪問問題,我解決了這個問題。 現在,我繼續得到的錯誤是“與底層事務管理器的通信失敗了”。
我們在數據庫中有一些客戶配置文件,當這些配置文件過時時,我們希望將它們移動到“存檔”數據庫進行存儲。 此舉簡單(幽默斜體)將它們添加到存檔數據庫並從主/實時數據庫中刪除它們。 我為每個數據庫都有一個DataContext。 下面的代碼執行Add,然后在嘗試使用第二個DataContext時獲取Delete上的錯誤。 我只和LINQ合作了幾個月,過去幾天我一直在搜索文章。 我想知道我的代碼是否有任何問題,或者是否仍有未正確配置的DTC或???
我們在VMware上運行我的工作站和服務器。 - Workstation是Windows 7 SP1 - 服務器是Windows和SQL Server 2008R2
“移動”的常規:
private int MoveProfileToArchiveDB( int iProfileId )
{
int rc = RC.UnknownError;
// get new Archive profile object
ProfileArchive.ProfileInfo piArchive = new ProfileArchive.ProfileInfo();
// 'Live' DataContext
using ( ProfileDataContext dbLive = new ProfileDataContext() )
{
// get Live profile
ProfileInfo piLive = ProfileInfo.GetProfile( dbLive, iProfileId );
// copy Live data to Archive profile object... including the id
ProfileArchive.ProfileInfo.CopyFromLive( piLive, piArchive, true );
}
bool bArchiveProfileExists = ProfileArchive.ProfileInfo.ProfileExists( piArchive.id );
// make the move a transaction...
using ( TransactionScope ts = new TransactionScope() )
{
// Add/Update to Archive db
using ( ProfileArchiveDataContext dbArchive = new ProfileArchiveDataContext() )
{
// if this profile already exists in the Archive db...
if ( bArchiveProfileExists )
{
// update the personal profile in Archive db
rc = ProfileArchive.ProfileInfo.UpdateProfile( dbArchive, piArchive );
}
else
{
// add this personal profile to the archive db
int iArchiveId = 0;
piArchive.ArchiveDate = DateTime.Now;
rc = ProfileArchive.ProfileInfo.AddProfile( dbArchive, piArchive, ref iArchiveId );
}
// if Add/Update was successful...
if ( rc == RC.Success )
{
// Delete from the Live db
using ( ProfileDataContext dbLive = new ProfileDataContext() )
{
// delete the personal profile from the Profile DB
rc = ProfileInfo.DeleteProfileExecCmd( dbLive, iProfileId ); // *** ERROR HERE ***
if ( rc == RC.Success )
{
// Transaction End (completed)
ts.Complete();
}
}
}
}
}
return rc;
}
筆記:
任何幫助是極大的贊賞! 非常感謝...
我決定將此作為答案發布,而不是繼續交叉評論。
不要使用錯誤代碼。 這就是例外情況。 代碼流更難以閱讀,錯誤代碼返回邀請被忽略。 例外使代碼更易於閱讀,並且更不容易出錯。
如果使用TransactionScope,請記住始終明確設置隔離級別。 請參閱使用新的TransactionScope()認為有害 。 SERIALIZABLE的隱含隔離級別幾乎從未被要求,並且具有巨大的負面影響。
交易升級。 每當在事務范圍內打開多個連接時,它們就可以將事務升級為分布式事務。 行為因版本而異,有些人試圖將其記錄下來,例如。 TransactionScope:事務升級行為 :
SQL Server 2008比SQL Server 2005更加智能,並且可以自動檢測特定事務中的所有數據庫連接是否指向同一物理數據庫。 如果是這種情況,則事務仍為本地事務,並且不會升級為分布式事務。 不幸的是有一些警告:
- 如果嵌套了打開的數據庫連接,則事務仍會升級為分布式事務。
- 如果在事務中,與另一個持久資源建立連接,則事務會立即升級為分布式事務。
由於您的連接(來自使用的兩個數據上下文)指向不同的數據庫,即使在SQL Server 2008上,您的TransactionScope也會升級到分布式事務。
將您的申請納入DTC至少有兩種方式:
現在,如果你解決以下上面提到的文章,你的代碼應該是工作MSDTC通信,但我仍然相信這歸檔不應該在客戶端運行的代碼EF發生。 有更好的工具, SSIS是一個很好的例子。 運行SSIS的夜間計划作業將更有效地傳輸這些未使用的配置文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.