Sai*_*Sai 6 transactionscope c#-4.0 entity-framework-5
我在SQL Server 2008上使用EF5.0.我在同一个服务器实例上有两个数据库.我需要更新两个数据库上的表,并希望它们是同一个事务.所以我使用了TransactionScope.以下是代码 -
public void Save()
{
var MSObjectContext = ((IObjectContextAdapter)MSDataContext).ObjectContext;
var AWObjectContext = ((IObjectContextAdapter)AwContext).ObjectContext;
using (var scope = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadUncommitted
}))
{
MSObjectContext.SaveChanges(SaveOptions.DetectChangesBeforeSave);
AWObjectContext.SaveChanges(SaveOptions.DetectChangesBeforeSave);
scope.Complete();
}
}
Run Code Online (Sandbox Code Playgroud)
当我使用上面的代码时,事务被提升为DTC.在互联网上搜索后,我发现这是因为两个不同的连接串/连接.但我不明白的是,如果我在一个数据库上编写存储过程,该数据库更新不同数据库中的表(在同一服务器上),则不需要DTC.那么为什么EF或TransactionScope会将其推广到DTC?还有其他的解决方法吗?
请指教
提前致谢
西
使用plain DbConnections,您可以通过使用相同的连接字符串(使用您喜欢的任何数据库)来防止同一服务器上的多个数据库进行DTC升级,并手动更改打开的连接对象上的数据库,如下所示:
using (var tx = new TransactionScope())
{
using (var conn = new SqlConnection(connectStr))
{
conn.Open();
new SqlCommand("INSERT INTO atest VALUES (1)", conn).ExecuteNonQuery();
}
using (var conn = new SqlConnection(connectStr))
{
conn.Open();
conn.ChangeDatabase("OtherDB");
new SqlCommand("INSERT INTO btest VALUES (2)", conn).ExecuteNonQuery();
}
tx.Complete();
}
Run Code Online (Sandbox Code Playgroud)
这不会升级到DTC,但如果你使用不同的值,它会connectStr.
我不熟悉EF以及它如何管理连接和上下文,但使用上述见解,您可以通过执行a conn.ChangeDatabase(..)然后创建上下文来避免DTC升级new DbContext(conn, ...).
但请注意,即使使用共享连接字符串,只要您同时打开两个连接,DTC就会参与其中,就像在此修改示例中一样:
using (var tx = new TransactionScope())
{
using (var conn = new SqlConnection(mssqldb))
{
conn.Open();
new SqlCommand("INSERT INTO atest VALUES (1)", conn).ExecuteNonQuery();
using (var conn2 = new SqlConnection(mssqldb))
{
conn2.Open();
conn2.ChangeDatabase("otherdatabase");
new SqlCommand("INSERT INTO btest VALUES (2)", conn2).ExecuteNonQuery();
}
}
tx.Complete();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1913 次 |
| 最近记录: |