如何减少Progress OpenEdge OdbcCommand使用ReadCommitted事务在C#中报告锁定所需



我们正在编写一个例程,该例程返回一个可编辑对象,或者返回一个表示底层记录已锁定的状态对象。

我们使用C#和.NET Framework 4.8以及Progress OpenEdge ODBC驱动程序来对抗OpenEdge数据库。记录可能被遗留的ABL代码锁定,这就是为什么我们想检查ReadCommitted事务,看看我们开始编辑它是否安全

从功能上讲,代码运行良好,完全按照我们的预期执行。当底层记录未锁定时,它会在几毫秒内返回对象;当它被锁定时,它返回一个描述记录的锁定状态的对象。

但是,当基础记录确实被锁定时,需要超过15秒才能返回预期的"ERROR[HY000][DataDirect][ODBC Progress OpenEdge Wire Protocol driver][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,用于限制客户端等待具有共享或独占锁定的记录的时间效果,对于隔离级别为的SQL客户端不需要READ UNCOMITTED,因为它将读取具有共享或专属锁定。

PROSQL_LOCKWAIT_TIMEOUT环境变量使您能够确定SQL客户端在锁定队列中等待特定记录。环境变量必须出现在broker启动并应用于经纪人

最小超时值默认为5秒(DFLT_LOCKWAIT-TIMEOUT(。最大超时值限制为4294967295秒或1193046.5小时的32位整数值。

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

UNIX:PROSQL_LOCKWAIT_TIMEOUT=30;导出PROSQL_LOCKWAIT_TIMEOUT

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

在OpenEdge 11.4及更高版本中,有一个-SQLLockWaitTimeout启动可用于实现与环境变量。参见文章:000064602,什么是-SQLLockWaitTimeout参数?以获取更多信息。

最新更新