如何减少使用ReadCommitted事务处理Progress OpenEdge OdbcCommand报告C#中的锁定所花费的时间?

问题描述 投票:1回答:1

我们正在编写一个例程,该例程将返回一个可编辑的对象,或者是一个表明基础记录已锁定的状态对象。

我们正在将C#和.NET Framework 4.8与针对OpenEdge数据库的Progress OpenEdge ODBC驱动程序配合使用。该记录可能已被旧的ABL代码锁定,这就是为什么我们要检查ReadCommitted事务以查看是否可以安全地对其进行编辑。

在功能上,代码可以正常工作,完全可以完成我们期望的工作。当基础记录未锁定时,它将在几毫秒内返回对象;锁定后,它返回一个描述记录锁定状态的对象。

但是当基础记录确实被锁定时,它需要花费15秒钟以上的时间才能返回预期的“ ERROR [HY000] [DataDirect] [ODBC Progress OpenEdge Wire Protocol驱动程序] [OPENEDGE]从表PUB中获取记录锁定失败.i-mst。“

我曾尝试减小CommandTimeout值,但最终(最终,随着我逐渐减小它)最终将失败更改为超时错误。

是否有一些较低级别的设置来控制ODBC或OpenEdge在失败之前等待多长时间才能释放锁?

这里是代码:

        public static dynamic ReadOdbcForEdit(OdbcConnection connection, string type, string criteria, string domain,
            string parentClass, string application)
        {
            connection.Open();
            var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);
            Type objectType = Object.GetJohnstonType(parentClass + type, domain, application);
            var tempObj = Activator.CreateInstance(objectType);

            try
            {
                var odbcCommand = new OdbcCommand(criteria)
                {
                    Connection = connection,
                    Transaction = transaction,
                    CommandTimeout = 30
                };

                var reader = odbcCommand.ExecuteReader();

                while (reader.Read())
                {

                    foreach (var property in tempObj.GetType().GetProperties())
                    {

                        var propertyType = property.PropertyType;
                        var propertyName = property.Name;

                        if (propertyType.IsArray ||
                            propertyType.IsGenericType &&
                            propertyType.GetGenericTypeDefinition() == typeof(List<>))
                        {
                            continue;
                        }

                        try
                        {
                            if (reader[propertyName].GetType() != typeof(DBNull))
                            {
                                property.SetValue(tempObj, reader[propertyName]);
                            }
                        }
                        catch (Exception e)
                        {
                            Logging.Message($"Could not fill {propertyName} from database column");
                            Logging.Exception(e);
                        }
                    }

                } 

                return tempObj;
            }
            catch (Exception e)
            {
                var openRecordStatus = new OpenRecordStatus
                {
                    StatusCode = e.HResult,
                    StatusMessage = e.Message
                };
                return openRecordStatus;
            }
        }
c# odbc openedge progress-db datadirect
1个回答
0
投票

您可能想要调整-SQLLockWaitTimeout

https://knowledgebase.progress.com/articles/Article/What-is-the-SQLLockWaitTimeout-Parameter

-SQLLockWaitTimeout参数用于标识发生锁冲突时需要等待的秒数。默认值为5秒。

此值适用于SQL遇到的所有锁冲突应用程序。因此,安装过程中会发生很多锁定冲突(进行了大量更新)将要考虑更改的影响此参数。

对于Progress的较旧版本(11.4之前的版本:https://knowledgebase.progress.com/articles/Article/P123923

PROSQL_LOCKWAIT_TIMEOUT环境变量是在9.1D06,用于限制客户端等待具有共享或独占锁定的记录的时间。此设置不效果,隔离级别为READ UNCOMMITTED,因为它将读取具有共享或独占锁定。

PROSQL_LOCKWAIT_TIMEOUT环境变量使确定SQL客户端将在锁定队列中等待多长时间特定记录。环境变量必须在代理已启动,并应用于代理的每个SQL连接经纪人。

最小超时值是默认的五秒(DFLT_LOCKWAIT-TIMEOUT)。最大超时值限制为32位整数值4,294,967,295秒或1,193,046.5小时。

此环境变量可以在启动数据库之前进行设置经纪人或AdminServer。例如,将其设置为30秒:

UNIX:PROSQL_LOCKWAIT_TIMEOUT = 30;导出PROSQL_LOCKWAIT_TIMEOUT

Windows:控制面板->系统->高级选项卡->环境变量->系统变量。添加一个新变量。

在OpenEdge 11.4和更高版本中,有-SQLLockWaitTimeout启动可用于实现与目标相同的目标的参数环境变量。请参阅文章:000064602,什么是-SQLLockWaitTimeout参数?有关其他信息。

© www.soinside.com 2019 - 2024. All rights reserved.