0

У нас есть приложение asp.net MVC, использующее Telerik Open Access. У нас есть всевозможные проблемы, которые просто сохраняют данные, как только мы вводим их в производство. Telerik больше не поддерживает Open Access, поэтому мы не можем получить от них никакой помощи, но мы должны жить прямо сейчас, и теперь у вас нет бюджетных часов. Может ли кто-нибудь дать мне несколько советов о том, как обойти эти проблемы?Как устранить ошибки «несколько потоков» и «новая транзакция не допускается» при использовании открытого доступа Telerik?

Мы получаем те же ошибки при обновлении и вставке записей, но эти проблемы не всегда происходят. Я никогда не получаю эти ошибки от решения Visual Studio на моем компьютере или после развертывания проекта на нашем тестовом сервере. На рабочем сервере, когда несколько пользователей используют приложение, мы начинаем видеть ошибки.

Пример кода будет эта вставка функции:

public void CreateAttachments(tblCoDoc obj) 
{ 
    try 
    { 
     dat.Add(obj); 
     dat.SaveChanges(); 
    } 
     catch (Exception exception) 
     { 
      throw exception; 
     } 
} 

и эта функция обновления:

public void UpdateWorkOrderApprGen(tblWorkOrder obj) 
    { 
     var context = new KoorsenOpenAccessContext(); 
     var upd = 
     (
      from workOrder in dat.tblWorkOrders 
      where workOrder.WorkOrderId == obj.WorkOrderId 
      select workOrder 
     ).FirstOrDefault(); 

     if (upd != null) 
     { 
      upd.ReferenceNumber = obj.ReferenceNumber; 
      upd.CustomerContract = obj.CustomerContract; 
      upd.VendorContract = obj.VendorContract; 
      upd.DateResolved = obj.DateResolved; 

      try 
      { 
       context.SaveChanges(); 
      } 
      catch (Exception ex) 
      { 
       throw ex; 
      } 
     } 
    } 

В обоих случаях эти методы в классе называется Repository. Существует частная переменная, определенная для данного класса (KOpenAccessContext это класс, определенный в проекте реализации класса OpenAccessContext):

private static KOpenAccessContext dat = null; 

, а затем в Repository конструктору, что частная переменная присваивается новый KOpenAccessContext:

dat = new KoorsenOpenAccessContext(); 

сообщения об ошибках мы получаем в

Telerik.OpenAccess.Exceptions.DataStoreException: Telerik.OpenAccess.RT.sql.SQLException: New transaction is not allowed because there are other threads running in the session.

и

[InvalidOperationException: Unable to start second transaction]

Первый из них наиболее распространен.

Этот пост: SqlException from Entity Framework - New transaction is not allowed because there are other threads running in the session. предполагает, что проблема заключается в сохранении в цикле for, что не так.

3-й ответ вниз предполагает ввод кода в транзакцию using и использование блоков контекста; Я получаю эту ошибку:

Telerik.OpenAccess.OpenAccessException: System.InvalidOperationException: This SqlTransaction has completed; it is no longer usable.

Я нашел этот пост: http://www.telerik.com/forums/how-do-i-fix-a-new-transaction-is-not-allowed-error-is-telerik-open-access#swcnW_tPGEWglUih1TEAKg предполагая, что я создаю «использовать короткие примеры живого контекста». Для меня это означало создать новый Open Access. Я попробовал это, и еще есть «новая сделка не допускается» Ошибка:

public void CreateAttachments(tblCoDoc obj) 
{ 

    try 
    { 
     var db = new KoorsenOpenAccessContext(); 
     db.Add(obj); 
     db.SaveChanges(); 
    } 
     catch (Exception exception) 
     { 
      throw exception; 
     } 
} 

Я действительно в растерянности и у меня есть клиент, и босс, глядя мне для решения. Мне бы хотелось узнать причину этого (думая, что это может быть потому, что есть несколько пользователей), но мне действительно нужно решение. Как я могу обойти эту проблему?

+0

Сделать контекст нестационарным. Я не знаю OA, но из вашего описания очевидно, что контекст не является потокобезопасным. –

+0

Можете ли вы привести мне пример, как это сделать? Какой «контекст» вы имеете в виду и как сделать его нестационарным? Где в коде будут такие изменения? – boilers222

+0

'частный статический KOpenAccessContext dat'. Где бы вы ни использовали его, убедитесь, что это новый экземпляр, как «контекст» в «UpdateWorkOrderApprGen». –

ответ

0

Я думаю, что у вас есть пара проблем.Вы упоминаете вы используете шаблон репозитория с частным статического контекстом, который инициализируется с этим кодом:

dat = new KoorsenOpenAccessContext(); 

Если ваши создания и функция обновления находится внутри хранилища, то они должны использовать этот экземпляр (dat) контекст и не идет о создании своих собственных функциональных частных случаев:

public void UpdateWorkOrderApprGen(tblWorkOrder obj) 
    { 
     // Don't do this, use the repository instance of the context instead 
     // var context = new KoorsenOpenAccessContext(); 
     var upd = 
     (
      from workOrder in dat.tblWorkOrders 
      where workOrder.WorkOrderId == obj.WorkOrderId 
      select workOrder 
     ).FirstOrDefault(); 

     if (upd != null) 
     { 
      upd.ReferenceNumber = obj.ReferenceNumber; 
      upd.CustomerContract = obj.CustomerContract; 
      upd.VendorContract = obj.VendorContract; 
      upd.DateResolved = obj.DateResolved; 

      try 
      { 
       dat.SaveChanges(); // Use the repository's context here 
      } 
      catch (Exception ex) 
      { 
       throw ex; 
      } 
     } 
    } 

Убедитесь, что хранилище реализует IDisposable и выбрасывания из контекста репозитория правильно по телефону dat.Dispose()

Другой вариант - пропустить шаблон репозитория и удалить экземпляр частного контекста репозитория (dat). Вместо этого используйте частный экземпляр функции контекста. Передовые методы Telerik OpenAccess предлагают использовать инструкцию для обеспечения того, чтобы контекст был закрыт и правильно утилизирован:

public void CreateAttachments(tblCoDoc obj) 
{  
    try 
    { 
     using (var db = new KoorsenOpenAccessContext()) 
     { 
      db.Add(obj); 
      db.SaveChanges(); 
     } 
    } 
    catch (Exception exception) 
    { 
     throw exception; 
    } 
}