我有一个使用EnterpriseLibrary和Unity的应用,并且只在一个地方使用TransactionScope。这很好用,尽管它针对SQL Server 2005运行:
// Execute a stored proc using a DbDatabase object inserted by Unity
using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
// Update something using the same DbDatabase object
// Run the stored proc above, again
// Assert that the results are different than from the previous call.
}
是的,这故意在没有scope.Complete()
的情况下结束:示例来自测试。
我刚开始有另一个应用程序。它使用Entity Framework 4.1。它访问同一服务器上的同一数据库。我尝试使用TransactionScope
,同时考虑“改变,验证更改,回滚更改”的想法。
using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
using(ProjectEntities db = new ProjectEntities())
{
Assert.IsFalse(db.tblEntities.Any(e=>e.X == desired_value));
db.tblEntities.Add(new tblEntity() { X = desired_value });
db.SaveChanges();
Assert.IsTrue(db.tblEntities.Any(e=> e.X == desired_value));
}
}
由于非常熟悉的MSDTC未启用网络访问错误而失败。
现在,这一分钟,第一个项目的第一个测试成功,第二个测试失败。
所以我有两个问题:
有没有办法重新调整我的第二个测试,以防止事务升级到MSDTC?
有人知道为什么我从这两个框架得到不同的结果吗? EntLib是否在整个使用过程中保持单个连接分配和打开? EF会做相反的事吗?
答案 0 :(得分:1)
我已经对EF,EntLib DAAB和TransactionScope进行了很多测试。
您必须考虑几点。
我不记得其他组合,但是对于SQL Server 2008或更高版本,EF5和Entlib 5,您可以在同一TransactionScope
中注册多个DbContexts和DAAB操作,而无需向MSDTC进行扩展。 但是有一个非常棘手的部分:
第二部分是最令人困惑的:当你使用连接字符串到EF时,它会改变它的格式,但是EntLib在配置文件的连接字符串中使用它。因此,您需要做的是调试代码,并记下EF使用的连接字符串的修改版本。您可以在ctx.Database.Connection.ConnectionString
中找到它,其中ctx是您正在使用的DbContext。完成后,只需将连接字符串的修改版本复制并粘贴到配置文件中,EF和EntLib都将使用相同的连接字符串,因此不会升级到MSDTC。
对于以前版本的SQL Server(有时取决于EF版本),您可以找到不同的问题,但本指南可以帮助您测试您的确切设置。
答案 1 :(得分:0)
我不知道EnterpriseLibrary,但EF会为每个查询创建并打开新连接,我认为这就是您看到这些不同结果的原因。
您可以通过手动打开两个DbConnection来验证这一点。