OracleCommand超时 [英] OracleCommand timeout

查看:331
本文介绍了OracleCommand超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ODP.NET OracleCommand.CommandTimeout的文档

默认值为0秒,没有时间限制.

Default is 0 seconds, which enforces no time limit.

当指定的超时值在命令执行之前到期时 完成后,命令将尝试取消.如果取消 成功,ORA-01013的消息引发异常:用户 请求取消当前操作.如果命令及时执行 没有任何错误,不会引发任何异常.

When the specified timeout value expires before a command execution finishes, the command attempts to cancel. If cancellation is successful, an exception is thrown with the message of ORA-01013: user requested cancel of current operation. If the command executed in time without any errors, no exceptions are thrown.

在多个OracleCommand对象使用相同对象的情况下 连接,其中一个OracleCommand对象的超时到期 可以终止单个连接上的任何执行.使 OracleCommand的超时到期仅取消其自己的命令 执行,对于每个连接,只需对每个连接使用一个OracleCommand OracleCommand将CommandTimeout属性设置为大于 0.

In a situation where multiple OracleCommand objects use the same connection, the timeout expiration on one of the OracleCommand objects may terminate any of the executions on the single connection. To make the timeout expiration of a OracleCommand cancel only its own command execution, simply use one OracleCommand for each connection if that OracleCommand sets the CommandTimeout property to a value greater than 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对象-cmd1cmd2,并且cmd1已经超时(按预期). 但是,根据文档,cmd2也不应运行.但是它仍然可以正常运行,并且可以正确更新另一行.

I am using the same OracleConnection object for both the command objects - cmd1 and cmd2, and cmd1 already timed out(as expected). But, per the documentation, cmd2 also should not run. But it still runs without any exception and updates the other row properly.

推荐答案

您在该连接上没有运行多个命令,而是有两个命令按顺序运行,一个接一个.当第一个命令超时时,连接上没有其他未决命令.在第一个命令成功执行或引发异常之后,您的代码才会提交第二个命令以供执行.

You do not have multiple commands running on the connection, you have two commands running sequentially, one after the other. When the first command times out, there is no other command pending on the connection. Your code does not submit the second command for execution until after the first command has either succeeded or has thrown an exception.

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

The last paragraph from the documentation you quoted should read: In a situation where multiple OracleCommand objects use the same connection simultaneously, ...

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超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆