When using a generic DbCommand to perform an update, it will hang indefinately if the row being updated is locked.
The underlying connection used is is Devart's Oracle provider, Devart.Data.Oracle.OracleConnection
Setting the DbCommand.CommandTimeOut has no effect at all, the update never times out.
DbCommand does not implement BeginExecuteNonQuery, so there seems to be no way to use DbConnection/DbCommand in an asynchronous manner.
I am able to get around this by using Devart's OracleCommand and BeginExecuteQuery, but it does .
Is there a way to do this in a generic way?
Simplified code for the oracle specific logic:
public bool TestAsyncUpdateRowOracle(string key, OracleConnection con, string sql)
{
const int timoutIterations=10;
bool updateOk=false;
OracleCommand cmd = new OracleCommand(sql, con);
cmd.Parameters.Add(Util.CreateParameter(dbSrcFactory, DbType.String, 16, "key"));
cmd.CommandType = CommandType.Text;
cmd.Parameters[0].Value = key.ToString();
IAsyncResult result = cmd.BeginExecuteNonQuery();
int asyncCount = 0;
while (!result.IsCompleted)
{
asyncCount++;
if (asyncCount > timeoutIterations)
{
break;
}
System.Threading.Thread.Sleep(10);
}
if (result.IsCompleted)
{
int rowsAffected = cmd.EndExecuteNonQuery(result);
Console.WriteLine("Done. Rows affected: " + rowsAffected.ToString());
}
else
{
try
{
cmd.Cancel();
Console.WriteLine("Update timed out, row is locked");
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.WriteLine("Unable to cancel update");
}
}
cmd.Dispose();
}