Sql server 如果其中一个数据库是只读的,是否会发生分布式事务升级?
我们正在执行从源数据库到目标数据库的导入过程。我们需要经常以自动化的方式运行这些导入 源服务器与目标服务器位于不同的服务器上。这两位都是SQL 2008女士。我们使用Linq2SQL访问源,使用自定义数据层访问目标。我们从不修改源数据库(尽管我们目前不将其恢复为只读)。但是,现在,当我们在transactionScope中运行导入时,整个事务将升级为DTC,因为我们在不同的服务器上访问两个DB 如果我们将源数据库设为只读,它还会这样做吗 关于如何在这种情况下避免DTC升级的任何其他建议 Remus回答的后续问题(再次感谢): 后续行动#1: 我的导入例程的结构是,它从源导入记录,并在目标中创建新记录。像这样:Sql server 如果其中一个数据库是只读的,是否会发生分布式事务升级?,sql-server,transactions,transactionscope,msdtc,Sql Server,Transactions,Transactionscope,Msdtc,我们正在执行从源数据库到目标数据库的导入过程。我们需要经常以自动化的方式运行这些导入 源服务器与目标服务器位于不同的服务器上。这两位都是SQL 2008女士。我们使用Linq2SQL访问源,使用自定义数据层访问目标。我们从不修改源数据库(尽管我们目前不将其恢复为只读)。但是,现在,当我们在transactionScope中运行导入时,整个事务将升级为DTC,因为我们在不同的服务器上访问两个DB 如果我们将源数据库设为只读,它还会这样做吗 关于如何在这种情况下避免DTC升级的任何其他建议 Remu
using(var scope = new TransactionScope())
{
// read some from source db using Linq2Sql
// transform source info
// update destination
// read some more from source db using Linq2Sql
// transform source info
// update destination
}
您是说在TransactionScope中围绕Linq2Sql位使用RequiresNew吗?或者,我想,因为我真的不关心源代码处的事务,所以我可以用事务来处理抑制,以将该连接包含在任何事务中,对吗
后续行动#2:
当你说“打开第二个连接,即使是到同一个数据库”——我已经读到了一些关于这个的变化:
在事务作用域内打开第二个ADO.Net连接时,两个连接都将升级为DTC。即使是同一数据库的新连接,也无所谓。数据库只读也与此无关,不可能与之有任何关系。首先,连接不是特定于数据库的,因为它们可以在打开后更改数据库。其次,只读数据库可以执行大量的写入操作(例如,可以调用readonlydb.dbo.myProcedure,在该过程中,我可以更新writeabledb.dbo.table) 如果要避免DTC,则必须在两个访问层之间使用不同的事务作用域(即使用REQUIRE创建新的作用域) 更新 如果可以在范围外进行读取,则最好:
// read some from source db using Linq2Sql
// read some more from source db using Linq2Sql
using(var scope = new TransactionScope())
{
// transform source info
// update destination
// transform source info
// update destination
}
但我知道这是不太可能的,因为第二组读取通常取决于第一次转换/更新的结果。因此,在执行读取时,您最好将范围限制在最上面:
using(var scope = new TransactionScope())
{
using(var nada= new TransactionScope(TransactionScopeOption.Supress))
{
// read some from source db using Linq2Sql
// transform source info
}
// update destination
using(var nada= new TransactionScope(TransactionScopeOption.Supress))
{
// read some more from source db using Linq2Sql
// transform source info
}
// update destination
}
顺便说一句,我假设“使用linq读取一些数据”意味着您实际枚举了查询,而不仅仅是创建查询表达式并在以后使用该表达式。我不知道事务作用域是如何与查询表达式交互的,但我的假设是该作用域应用于查询执行,而不是声明。谢谢您的回答。我确实有几个后续问题-在原始问题的上面。是选项1:使用相同的连接字符串新建SqlConnection.Open()。必须将其登记到DTC中。因此,到同一个资源管理器的两个不同连接需要在DTC中注册。顺便说一句,到不同RMs的两个连接显然也需要注册到DTC中,我意识到,与我前面的评论相比,这可能表明相反的情况,这是愚蠢的。