0

我们有一个使用 Telerik Open Access 的 asp.net MVC 应用程序。一旦我们将数据投入生产,我们就会遇到各种各样的问题。Telerik 不再支持 Open Access,因此我们无法从他们那里获得任何帮助,但我们应该立即上线,并且现在没有预算的时间来更改。有人可以就如何解决这些问题给我一些建议吗?

我们在更新和插入记录时遇到了同样的错误,但这些问题并不总是发生。在我的计算机上从 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:不允许新事务,因为会话中正在运行其他线程。

[InvalidOperationException:无法启动第二个事务]

第一个是最常见的。

这篇文章:来自实体框架的 SqlException - 不允许新事务,因为会话中还有其他线程正在运行。表明问题出在 for 循环中的保存,但事实并非如此。

第三个答案建议将代码放在使用事务和使用上下文块中;我收到此错误:

Telerik.OpenAccess.OpenAccessException:System.InvalidOperationException:此 SqlTransaction 已完成;它不再可用。

我发现这篇文章:http ://www.telerik.com/forums/how-do-i-fix-a-new-transaction-is-not-allowed-error-is-telerik-open-access#swcnW_tPGEWglUih1TEAKg建议我创建“使用短暂的上下文实例”。对我来说,这意味着创建一个新的开放获取。我试过了,但仍然出现“不允许新交易”错误:

public void CreateAttachments(tblCoDoc obj)
{

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

我真的很茫然,我有一个客户和老板向我寻求解决方案。我很想知道造成这种情况的原因(认为可能是因为有多个用户),但我真正需要的是一个解决方案。我怎样才能解决这个问题?

4

1 回答 1

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 最佳实践建议使用 using 语句来确保正确关闭和处理上下文:

public void CreateAttachments(tblCoDoc obj)
{    
    try
    {
        using (var db = new KoorsenOpenAccessContext())
        {
            db.Add(obj);
            db.SaveChanges();
        }
    }
    catch (Exception exception)
    {
        throw exception;
    }
}
于 2017-01-19T13:32:10.313 回答