如何减少Progress OpenEdge OdbcCommand使用ReadCommitted事务报告C#中的锁所需的时间?
我们正在编写一个例程,它要么返回一个可编辑对象,要么返回一个表示底层记录已锁定的状态对象 我们正在对OpenEdge数据库使用C#和.NET Framework 4.8以及Progress OpenEdge ODBC驱动程序。记录可能会被遗留ABL代码锁定,这就是为什么我们要检查ReadCommitted事务,以确定开始编辑它是否安全 从功能上讲,代码运行良好,完全符合我们的预期。当底层记录未锁定时,它会在毫秒内返回对象;当它被锁定时,它返回一个描述记录锁定状态的对象 但当底层记录确实被锁定时,需要15秒以上的时间才能返回预期的“错误[HY000][DataDirect][ODBC Progress OpenEdge Wire Protocol driver][OpenEdge]无法从表PUB.i-mst中获取记录锁。” 我尝试过减小CommandTimeout值,但这只是(最终,随着我逐渐减小它)最终将失败更改为超时错误 是否有一些较低级别的设置来控制ODBC或OpenEdge在失败之前等待锁释放所需的时间 代码如下:如何减少Progress OpenEdge OdbcCommand使用ReadCommitted事务报告C#中的锁所需的时间?,c#,odbc,openedge,progress-db,datadirect,C#,Odbc,Openedge,Progress Db,Datadirect,我们正在编写一个例程,它要么返回一个可编辑对象,要么返回一个表示底层记录已锁定的状态对象 我们正在对OpenEdge数据库使用C#和.NET Framework 4.8以及Progress OpenEdge ODBC驱动程序。记录可能会被遗留ABL代码锁定,这就是为什么我们要检查ReadCommitted事务,以确定开始编辑它是否安全 从功能上讲,代码运行良好,完全符合我们的预期。当底层记录未锁定时,它会在毫秒内返回对象;当它被锁定时,它返回一个描述记录锁定状态的对象 但当底层记录确实被锁定时,
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;
}
}
public静态动态ReadOdbcForEdit(OdbcConnection连接、字符串类型、字符串条件、字符串域、,
字符串父类,字符串应用程序)
{
connection.Open();
var事务=connection.BeginTransaction(IsolationLevel.ReadCommitted);
类型objectType=Object.getjohnstotype(父类+类型、域、应用程序);
var tempObj=Activator.CreateInstance(objectType);
尝试
{
var odbcCommand=新的odbcCommand(标准)
{
连接=连接,
交易=交易,
CommandTimeout=30
};
var reader=odbcCommand.ExecuteReader();
while(reader.Read())
{
foreach(tempObj.GetType().GetProperties()中的var属性)
{
var propertyType=property.propertyType;
var propertyName=property.Name;
如果(propertyType.IsArray||
propertyType.IsGenericType&&
propertyType.GetGenericTypeDefinition()==typeof(列表))
{
继续;
}
尝试
{
if(reader[propertyName].GetType()!=类型of(DBNull))
{
SetValue(tempObj,reader[propertyName]);
}
}
捕获(例外e)
{
Message($“无法从数据库列填充{propertyName}”);
例外情况(e);
}
}
}
返回tempObj;
}
捕获(例外e)
{
var openRecordStatus=新的openRecordStatus
{
状态代码=e.HResult,
StatusMessage=e.Message
};
返回openRecordStatus;
}
}
您可能需要调整-SQLLockWaitTimeout
-SQLLockWaitTimeout参数用于标识
发生锁冲突时等待的秒数。默认值为5秒
此值适用于SQL遇到的所有锁冲突
应用。所以一个安装会有很多锁冲突
(有很多更新)会考虑改变的影响吗?
这个参数
对于较旧版本的Progress(11.4之前的版本):
PROSQL_LOCKWAIT_TIMEOUT环境变量是在中引入的
9.1D06,用于限制客户端等待具有共享或独占锁定的记录的时间。此设置不可用
隔离级别为的SQL客户端不需要
读取未提交,因为它将读取具有共享或
对它的独占锁
PROSQL_LOCKWAIT_TIMEOUT环境变量使您能够
确定SQL客户端将在锁定队列中等待
特别记录。环境变量必须出现在
代理将启动并应用于的每个SQL连接
经纪人
最小超时值默认为5秒
(DFLT_锁定等待超时)。最大超时值限制为
4294967295秒或1193046.5小时的32位整数值
可以在启动数据库之前设置此环境变量
代理或管理员服务器。例如,要将其设置为30秒:
UNIX:PROSQL_LOCKWAIT_TIMEOUT=30;导出PROSQL\u锁定等待\u超时
Windows:控制面板->系统->高级选项卡->环境
变量->系统变量。添加一个新变量
在OpenEdge 11.4及更高版本中,有一个-SQLLockWaitTimeout启动
参数,该参数可用于实现与
环境变量。参见文章:000064602,什么是
-SQLLockWaitTimeout参数?有关更多信息,请参阅
不幸的是,对于我们的环境来说,这可能不是一个选项,但我将咨询OpenEdge DBA。谢谢你的调查!只是好奇,但为什么这不是一个选择呢?这似乎正是你所要求的,所以我一定不理解你的要求。我们已经阅读了回复