我正在尝试将两个事务包装到同一个SQL Server上的不同数据库中,并遇到了一些困难。最初我在网络DTC访问方面遇到了问题,但现在我持续收到的错误是“与底层事务管理器的通信失败”。
我们在一个数据库中有一些客户配置文件,当这些配置文件过时时,我们希望将它们移动到“存档”数据库进行存储。移动只是简单地(为了幽默而使用斜体)将它们添加到归档数据库并从主/活动数据库中删除它们。我为每个数据库拥有一个DataContext。以下代码执行Add操作,然后在尝试使用第二个DataContext进行Delete操作时出现错误。我只使用LINQ工作了几个月,并搜索了过去几天的文章。我想知道我的代码是否存在问题,或者DTC是否配置正确。
我们在我的工作站和服务器上都运行在VMware上。 - 工作站是Windows 7 SP1 - 服务器是Windows和SQL Server 2008R2
“Move”程序如下:
我们在一个数据库中有一些客户配置文件,当这些配置文件过时时,我们希望将它们移动到“存档”数据库进行存储。移动只是简单地(为了幽默而使用斜体)将它们添加到归档数据库并从主/活动数据库中删除它们。我为每个数据库拥有一个DataContext。以下代码执行Add操作,然后在尝试使用第二个DataContext进行Delete操作时出现错误。我只使用LINQ工作了几个月,并搜索了过去几天的文章。我想知道我的代码是否存在问题,或者DTC是否配置正确。
我们在我的工作站和服务器上都运行在VMware上。 - 工作站是Windows 7 SP1 - 服务器是Windows和SQL Server 2008R2
“Move”程序如下:
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之外正常工作。
- ProfileInfo是主要的个人资料表,在Live和Archive数据库中大致相同。
非常感谢您的帮助!非常感谢...
DELETE ... OUTPUT ... INTO targetdb... FROM sourcedb ... WHERE
是一个很好的起点。SSIS作业是另一个很好的选择。甚至可以使用基于T-SQL游标的解决方案。只是不要通过客户端路由每一行...... - Remus Rusanu