代码之家  ›  专栏  ›  技术社区  ›  vzczc

有没有一种方法可以使用通用的dbcommand进行异步更新?

  •  1
  • vzczc  · 技术社区  · 15 年前

    当使用通用dbcommand执行更新时,如果要更新的行被锁定,它将不确定地挂起。

    使用的基础连接是Devart的Oracle提供程序devart.data.oracle.oracleConnection

    设置dbcommand.commandTimeout根本没有效果,更新永远不会超时。

    dbcommand不实现beginExecutionQuery,因此似乎没有办法以异步方式使用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();
    }
    
    2 回复  |  直到 14 年前
        1
  •  2
  •   Mauricio Scheffer    14 年前

    遗憾的是,没有,ADO.NET中没有具有异步操作的接口或基类(例如beginExecuteOnQuery/endExecuteOnQuery)。它们只存在于很少的ADO.NET提供程序实现中。(sqlclient,devart-oracle)。

    也就是说,如果在设置commandTimeout时它没有超时,在我看来,这是提供程序中的一个bug。

        2
  •  0
  •   DCookie    15 年前

    你能用nowait选项发出一个锁表吗?如果锁定失败,这将立即返回控制权,并出现错误。例如:

    LOCK TABLE employees
       IN EXCLUSIVE MODE 
       NOWAIT; 
    

    锁桌子有几种方法。 Here 是关于锁定的开发人员指南部分。 This 是lock table命令的SQL引用页。

    另一个选项是使用select。更新nowait语句以锁定要更新的行。除了更新语句外,这两个选项都需要向Oracle发出其他命令。

    推荐文章