1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

  2. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

How do I decrease the time it takes for a Progress OpenEdge OdbcCommand using ReadCommitted...

Discussão em 'StackOverflow' iniciado por fdantas, Novembro 1, 2019.

  1. fdantas

    fdantas Administrator Moderador

    We're writing a routine which either returns an editable object, or a status object that says the underlying record is locked.

    We're using C# and .NET Framework 4.8 with the Progress OpenEdge ODBC driver against an OpenEdge database. The record might be locked by legacy ABL code, which is why we want to check with a ReadCommitted transaction to see if it's safe for us to start editing it.

    Functionally, the code works fine, doing exactly what we expect it to do. When the underlying record is not locked, it returns the object in a matter of milliseconds; when it's locked, it returns an object that describes the locked status of the record.

    But when the underlying record is indeed locked it takes upwards of 15 seconds to return with the expected "ERROR [HY000] [DataDirect][ODBC Progress OpenEdge Wire Protocol driver][OPENEDGE]Failure getting record lock on a record from table PUB.i-mst."

    I have tried decreasing the CommandTimeout value, but that only (eventually, as I decrease it incrementally) ultimately changes the failure to a timeout error.

    Is there some lower-level setting to control how long either ODBC or OpenEdge takes to wait for a lock to be released before failing?

    Here's the code:

    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;
    }
    }

    Continue reading...

Compartilhe esta Página