我们正在编写一个例程,该例程将返回一个可编辑的对象,或者是一个表明基础记录已锁定的状态对象。
我们正在将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;
}
}
您可能想要调整-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参数?有关其他信息。