Asp.net EF4-如何在现有事务中登记?

Asp.net EF4-如何在现有事务中登记?,asp.net,entity-framework-4,transactions,Asp.net,Entity Framework 4,Transactions,我有一个使用asp.net mvc的web应用程序,我在一个基本控制器中创建我的EF上下文,并使其可用于整个请求,然后在基本控制器被释放时释放上下文。我希望能够将上下文的连接登记到会话中存储的现有事务中 使用以下命令启动新事务: ObjectContext context = new MyEntities(myConnectionString); DbTransaction transaction = context.Connection.BeginTransaction(); 然后将其存储在

我有一个使用asp.net mvc的web应用程序,我在一个基本控制器中创建我的EF上下文,并使其可用于整个请求,然后在基本控制器被释放时释放上下文。我希望能够将上下文的连接登记到会话中存储的现有事务中

使用以下命令启动新事务:

ObjectContext context = new MyEntities(myConnectionString);
DbTransaction transaction = context.Connection.BeginTransaction();
然后将其存储在当前会话中:

HttpContext.Current.Session["EFTransaction"] = transaction;
然后根据新请求从会话中检索事务并登记上下文:

context.Connection.EnlistTransaction(
(???)HttpContext.Current.Session["EFTransaction"]);
唯一的问题是我不知道该投什么。
BeginTransaction()
方法返回一个
System.Data.Common.DbTransaction
对象,并且
登记事务(System.Transactions.Transaction)
需要一个事务对象


我的目标基本上是在请求之间创建和修改相同的实体,然后在用户准备保存它们时将所有更改提交给数据库

不确定这是否是最佳方法,在多个页面请求之间保持事务打开,并在会话中存储将打开一个很长的、可能未提交的事务,这将持续获取表上的锁

最好的方法可能是在准备提交更改之前启动事务。在那里你可以像这样使用TransactionScope

using (var tscope = new TransactionScope()
 {
  ..... all changes here ...
  tscope.Complete()
 }
您不必显式注册作用域中的任何连接,在操作过程中打开的任何连接都将自动注册,如果您有任何打开的连接,它们将关闭并重新打开事务

如果您担心并发性问题,可以在表中使用基于时间戳的列


另外,让我补充一点,EF在调用save时隐式使用事务,只有在需要多个保存或默认事务级别(在Sql Server上读取提交)不够时才需要外部作用域。

不确定这是否是最佳方法,在多个页面请求之间保持事务打开,在会话中存储将打开一个非常长且可能未提交的事务,这将持续获取表上的锁

最好的方法可能是在准备提交更改之前启动事务。在那里你可以像这样使用TransactionScope

using (var tscope = new TransactionScope()
 {
  ..... all changes here ...
  tscope.Complete()
 }
您不必显式注册作用域中的任何连接,在操作过程中打开的任何连接都将自动注册,如果您有任何打开的连接,它们将关闭并重新打开事务

如果您担心并发性问题,可以在表中使用基于时间戳的列


另外,让我补充一点,当调用save时,EF隐式地使用事务,只有当需要多个保存时,或者当默认事务级别(在Sql Server上读取提交)不够时,才需要外部作用域。

会话中存储的事务?天哪

住手在会话中存储事务是非常错误的想法。现在返回分析并更改架构

为什么??假设您的应用程序由多个用户使用(是的,ASP.NET应用程序通常会使用这种情况)。现在,第一个用户在长时间运行的事务中启动数据修改。事务实际上与数据库通信,并对记录使用锁。因此,在第一次未提交更改之后,事务锁定了一些记录。现在,来自其他用户/事务的每个试图访问同一记录的查询都将等待修改事务完成(除非您允许读取未提交的数据,这与根本不使用事务几乎相同)。如果修改事务需要10分钟,则访问同一记录的所有其他用户将超时

这只是一个例子,为什么它是完全错误的想法。还有更像是死锁的高概率、SQL server上的性能问题、事务超时等

更糟糕的是,您的事务是分布式的,所以我怀疑它是否可以工作,因为当您决定提交时,来自事务中使用的所有上下文实例的连接必须处于活动状态,并且在您提交之前,它们不能被释放或重设(返回到连接池)

这是以完全不同的方式完成的:

将对象存储在会话中,并在用户完成所有更改时将其推送到数据库中-SaveChanges本身使用事务,因此,如果您将更改保存在一起,它们将处于事务中,并且在用户完成更改之前,没有理由保存它们。请注意,这并不意味着在会话中存储上下文


长时间运行的事务确实存在,但它们是“自定义实现的”。这意味着数据在没有事务的情况下被持久化到数据库中,并且您有单独的代码称为compensation,它可以恢复更改。在这种情况下,这是您不需要的。

存储在会话中的事务?天哪

住手
在会话中存储事务是非常错误的想法。现在返回分析并更改架构

为什么??假设您的应用程序由多个用户使用(是的,ASP.NET应用程序通常会使用这种情况)。现在,第一个用户在长时间运行的事务中启动数据修改。事务实际上与数据库通信,并对记录使用锁。因此,在第一次未提交更改之后,事务锁定了一些记录。现在,来自其他用户/事务的每个试图访问同一记录的查询都将等待修改事务完成(除非您允许读取未提交的数据,这与根本不使用事务几乎相同)。如果修改事务需要10分钟,则访问同一记录的所有其他用户将超时

这只是一个例子,为什么它是共同的