【问题标题】:DBTransaction closing when used for another methodDBTransaction 用于其他方法时关闭
【发布时间】:2013-07-23 10:40:30
【问题描述】:

我试图在我的实体框架存储库中对多个不同的插入/更新语句使用单个事务,但是每当我将事务传递给不同的方法时,它都会返回为关闭状态,见下文 -

ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
objectContext.Connection.Open();
DbTransaction transaction = objectContext.Connection.BeginTransaction();

using (transaction)
{
      IPersonRepository personRepository = new PersonRepository();
      context.Entry(person).State = System.Data.EntityState.Modified;
      personRepository.Update(person, objectRetrievedDateTime, transaction, objectContext);

      if (existingStatus != null)
      {
           objectContext.CreateObjectSet<tblPersonStatus>().Attach(existingStatus);
           existingStatus.EndDate = DateTime.Now;
           context.Entry(existingStatus).State = System.Data.EntityState.Modified;

           IPersonStatusesRepository repository = new PersonStatusesRepository();
           repository.Update(existingStatus, objectRetrievedDateTime, transaction, objectContext);
      }
}

到第一个更新方法(personRepository.Update)完成时,事务出现错误“base {System.SystemException} = {”This SqlTransaction has completed;它不再可用。"}"

有没有办法解决这个问题?

EDIT - 被调用的更新方法是这样的 -

public virtual void Update(T entity, DateTime? objectRetrievedDateTime, DbTransaction transaction, ObjectContext objectContext)
    {
        if (entity == null)
        {
            throw new ArgumentException("Cannot update a null entity.");
        }

        using (transaction)
        {
            ObjectStateEntry entry = objectContext.ObjectStateManager.GetObjectStateEntry(entity);

            string entityName = entity.GetType().Name;

            if (!objectRetrievedDateTime.HasValue || !this.AuditsAfterRetieval(objectRetrievedDateTime, entityName, entity))
            {
                Dictionary<string, object> oldValues = new Dictionary<string, object>();
                Dictionary<string, object> newValues = new Dictionary<string, object>();

                bool changed = this.EntityHasChanged(entity, entry, out oldValues, out newValues);

                // Check for changes before saving
                if (changed)
                {
                    this.context.SaveChanges();
                    this.Audit(entity, entityName, "Update", oldValues, newValues, false, null);
                }
            }
            else
            {
                throw new Exception("Object cannot be saved as it has been amended in another thread");
            }
        }
    }

【问题讨论】:

  • 您正在代码中的其他地方提交事务,但没有看到它没有人能说出来..
  • 在您的更新方法中您正在提交事务
  • 我已经在原帖中添加了更新方法,我也检查了任何其他被调用的方法,它们都没有提交事务。
  • @user1948635 你的更新方法代码错误:你不能把事务放到2个嵌套的using语句中
  • @user1948635 是的,对事务只使用一个 using 语句就足够了,然后在要使用该事务的所有更新方法中。当你到达 using 语句的右括号时,事务将被关闭

标签: c# asp.net entity-framework transactions


【解决方案1】:

你的问题是这个结构:

using (transaction)
{
   ...

  Update(transaction, ....)
}

退出时,事务是Disposed,所以也失效了。

【讨论】:

  • 令人惊讶的是直到我调用回滚时才真正抛出异常,有没有办法在我退出更新方法时保持事务打开?
  • 请勿将其包含在 using 语句中,或将其移出此方法。
【解决方案2】:

只需删除 Update 方法中的 using 语句

您正在使用 using 处理其中的事务

这是您应该如何使用事务的快速存根

using(DbConnection connection = ...)    
{    
    connection.Open();    
    using(DbTransaction transaction = connection.BeginTransaction(...))    
    {
      try{
        ... update ...
        ... another update ...

        transaction.Commit(); 
      }catch(Exception){
       // transaction rolled back here if an Exception is thrown before the call to Commit()
        transaction.Rollback()
      }   
    }     
} // connection closed here

【讨论】:

  • @user1948635 乐于助人:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多