使用通用DbCommand执行更新时,如果正在更新的行被锁定,它将无限期挂起。
使用的底层连接是Devart的Oracle提供程序Devart.Data.Oracle.OracleConnection
设置DbCommand.CommandTimeOut完全没有效果,更新永远不会超时。
DbCommand没有实现BeginExecuteNonQuery,因此似乎无法以异步方式使用DbConnection / DbCommand。
我可以通过使用Devart的OracleCommand和BeginExecuteQuery解决这个问题,但确实如此。
有没有办法以通用方式执行此操作?
oracle特定逻辑的简化代码:
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();
}
答案 0 :(得分:2)
可悲的是,不,ADO.NET中没有具有异步操作的接口或基类(例如BeginExecuteNonQuery / EndExecuteNonQuery)。它们仅存在于极少数ADO.NET提供程序实现中。 (SqlClient,Devart Oracle)。
也就是说,如果在设置CommandTimeOut时它没有超时,我认为这是提供者中的一个错误。
答案 1 :(得分:0)