Мы пишем подпрограмму, которая возвращает либо редактируемый объект, либо объект состояния, который говорит, что основная запись заблокирована.
Мы используем C # и .NET Framework 4.8 с драйвером ODBC Progress OpenEdge ODBCпротив базы данных OpenEdge. Запись может быть заблокирована унаследованным кодом 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;
}
}