我想设置实体框架,这样SavesChanges()就不会用BEGIN和COMMIT来包装它生成的所有SQL。我是在一个相关的SO question上看到这个建议的
using( var transation = new TransactionScope(TransactionScopeOption.Suppress) )
{
ObjectContext.SaveChanges();
}但这对我不起作用。我们使用的是MYSQL连接器,所以我确实通过单步执行源代码做了一些挖掘,我发现EntityFramework是请求创建新事务的那个,而不是连接器的错误,请参见以下堆栈跟踪。

接下来,我开始查看EF的源代码(EF 6是开源的,相关代码在反编译器中看起来是一样的)
var needLocalTransaction = false;
var connection = (EntityConnection)Connection;
if (connection.CurrentTransaction == null
&& !connection.EnlistedInUserTransaction
&& _lastTransaction == null)
{
needLocalTransaction = startLocalTransaction;
}
...
if (needLocalTransaction)
{
localTransaction = connection.BeginTransaction();
}好的,如果事务不存在,它会自己创建一个事务。并且进一步到如何在EF中建立当前事务我得到EF建立连接的代码
var currentTransaction = Transaction.Current;
EnsureContextIsEnlistedInCurrentTransaction(
currentTransaction,
() =>
{
Connection.Open();
_openedConnection = true;
_connectionRequestCount++;
return true;
},
false);这似乎是唯一一个使用"TransactionScopeOption.Suppress“行的地方,但是它所做的只是将环境事务(Transaction.Current)设置为null。强制EF看不到事务,做与我想要的相反的事情,并创建一个新的事务。
有没有人幸运地在EF5中关闭了事务,或者是我破解并构建自己版本的sql连接器的唯一解决方案?
谢谢!
发布于 2015-01-09 12:23:36
EF5是硬编码的,可以将插入和更新包装到事务中。在几乎所有情况下,这都是对多个实体进行批处理写入时所需的行为。
如果要更改这一点,则必须自己编写新代码,将其编译为适当的DLL,然后引用新代码。为了绕过一个非常重要的安全特性,需要做很多工作。我不推荐这样做。
问题是,您为什么这么想禁用事务?
它是否会导致性能问题?您是否发现事务的额外安全性对业务流程有害?
听起来您并不关心写操作是否丢失、是否发生了幻影读取等(我认为这是因为您想一起跳过所有事务),这不是一个好主意。
如果情况并非如此(我希望如此),并且您担心性能,那么也许您的事务级别隔离对于您想要的来说太高了?您可能希望将其他调用包装在设置了更低隔离级别(安全性较低,但锁定较少,因此性能更好)的事务中,如读取未提交?
https://stackoverflow.com/questions/17696065
复制相似问题