的OracleCommand超时(OracleCommand timeout)

2019-09-23 05:50发布

ODP.NET 为OracleCommand.CommandTimeout文件说

缺省为0秒,这强制没有时间限制。

当指定的超时值到期命令执行完成之前,指令试图取消。 如果取消成功,则将引发异常与ORA-01013的消息:用户请求取消当前操作。 如果命令的时间没有任何错误执行,没有异常抛出。

在多个的OracleCommand对象使用相同的连接的情况下,上的OracleCommand对象中的一个的期满超时可以在单个连接上终止任何处决。 为了使的OracleCommand的超时期满只取消了自己的命令执行,只需使用一个的OracleCommand每个连接如果的OracleCommand CommandTimeout属性设置为大于0的值。

但是,像这样的代码工作:

static void Main(string[] args)
{
    OracleConnection conn = null;
    try
    {
        string connString =
            "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=myOracleHost)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=myServiceName)));User Id=system;Password=admin;Pooling = False;";
        string cmdString1 = "UPDATE employee SET empname = 'temp1' where id = 1";
        string cmdString2 = "Update employee set empname = 'temp2' where id = 2";
        conn = new OracleConnection(connString);
        var cmd1 = new OracleCommand(cmdString1, conn);
        cmd1.CommandTimeout = 30;
        var cmd2 = new OracleCommand(cmdString2, conn);
        cmd2.CommandTimeout = 30;
        conn.Open();
        try
        {
            //Locked the row with ID 1 with an uncommitted update operation outside this code
            cmd1.ExecuteNonQuery();
        }
        catch (Exception exception)
        {
            //Exception ORA-01013 Thrown as expected
        }
        try
        {
            //As per the documentation, this should not also work since this command object also uses the same connection as above and it timed out in the query above
            cmd2.ExecuteNonQuery();
            //But this still works fine. 
        }
        catch (Exception)
        {
            //no exception
        }
    }
    finally
    {
        conn.Close();
    }
}

我使用的是相同OracleConnection对象两个命令对象- cmd1cmd2cmd1已超时(如预期)。 但是,每个文档, cmd2应该也不会运行。 但它仍然运行没有任何异常,并适当更新其他行。

Answer 1:

您没有连接上运行多个命令,你必须运行顺序,一前一后两个命令。 当第一命令超时,也没有其他命令未决的连接上。 您的代码不提交执行第二个命令,直到之后的第一个命令可能成功,也引发了异常。

从文档的最后一段你引用应为: 在多个对象的OracleCommand 同时使用同一个连接的情况下,...

static void Main(string[] args)
{
    using (var conn = new OracleConnection("Pooling=False;...")) // why?
    using (var cmd1 = conn.CreateCommand())
    using (var cmd2 = conn.CreateCommand())
    {
        cmd1.CommandText = "UPDATE employee SET empname = 'temp1' WHERE id = 1";
        cmd2.CommandText = "UPDATE employee SET empname = 'temp2' WHERE id = 2";
        cmd1.CommandTimeout = 30;
        cmd2.CommandTimeout = 30;

        conn.Open();

        // there are no commands on conn yet

        try { cmd1.ExecuteNonQuery(); } // cmd1 is the only command on conn
        catch (OracleException) { } // if timeout, no other command affected

        // cmd1 is no longer on conn

        try { cmd2.ExecuteNonQuery(); } // cmd2 is the only command on conn
        catch (OracleException) { } // if timeout, no other command affected

        // cmd2 is no longer on conn
    }
}


文章来源: OracleCommand timeout