After a day or so of running, Windows service starts giving OracleExceptions when trying to perform query

2

I have a Windows service created in .Net 4.0 that among other things need to do two things to an Oracle database. One is to run a SELECT query to see if a record with a user-given (through a telephony UI) ID exists, the other is to INSERT a new record into a table.

Everything works well, until the service has been running for a day or so - there is a degree of randomness here, some times it works for several days, mostly it just works for 24 hours after the service has been restarted.

Once the problem appears, I start getting OracleExceptions. A full exception is included towards the end of this question. The exceptions indicate that opening a socket to the server either failed, or it was closed by software on "my" machine.

Now, there are a few indications that this is not really a network/database error.

  1. I have a small console utility that uses exactly the same library code to read from the server. If I run this at the same time that the service is throwing exceptions left and right, it can verify data with the database server with no issues.

  2. If I restart the Windows service, normal operation resumes immediately.

So it would seem something gets "tired" after a while in my software. Now, the objects that handle the phone calls that ultimately lead to Oracle interaction are recreated per call - hopefully there should be no lifetime issues there. Likewise, when these objects need to talk to the Oracle server, a new OracleConnection object is created, and a new OracleCommand instansiated. These and the resulting OracleDataReader are closed and disposed explicitly (I've even stopped using the using()-pattern to make sure I'm really doing it). Here is and example of the code, after being reduced to something almost childlike in order to make sure it does what it should do:

    public bool CheckIfIdExists(string paramValue)
    {
        var result = false;

        var conn = new OracleConnection(_connectionString);
        conn.Open();
        var cmd = new OracleCommand("SQL query", conn)
        {
            CommandType = CommandType.Text
        };
        cmd.Parameters.Add("paramName", paramValue);

        var rdr = cmd.ExecuteReader();
        result = rdr.HasRows;

        rdr.Close();
        rdr.Dispose();

        cmd.Dispose();

        conn.Close();
        conn.Dispose();

        return result;
    }

As you can see I am not catching any exceptions here - they are handled further back in my code. And they occur on trying to open the connection.

I do not have the Oracle experience necessary to see why this is failing. It is extremely frustrating, because the problem goes away as soon as the service is restarted. Is there some connection pool that suddenly dries up because I'm not disposing of my resources correctly?

Here is the exception I am getting when trying to open the connection to the server once the problem appears:

Unhandled exception occurred in HandleCall: Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Network Session: Unexpected packet read error ---> OracleInternal.Network.NetworkException (0x80004005): Network Session: Unexpected packet read error ---> System.Net.Sockets.SocketException (0x80004005): An established connection was aborted by the software in your host machine
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at OracleInternal.Network.ReaderStream.Read(OraBuf OB)
   at OracleInternal.Network.ReaderStream.Read(OraBuf OB)
   at OracleInternal.TTC.OraBufReader.GetDataFromNetwork()
   at OracleInternal.TTC.OraBufReader.Read(Boolean bIgnoreData)
   at OracleInternal.TTC.TTCExecuteSql.ReceiveExecuteResponse(Accessor[]& defineAccessors, Accessor[] bindAccessors, Boolean bHasReturningParams, SQLMetaData& sqlMetaData, SqlStatementType statementType, Int64 noOfRowsFetchedLastTime, Int32 noOfRowsToFetch, Int32& noOfRowsFetched, Int64& queryId, Int32 longFetchSize, Int32 initialLOBFetchSize, Int64[] scnFromExecution, BindDirection[]& bindDirections, DataUnmarshaller& dataUnmarshaller)
   at Oracle.ManagedDataAccess.Client.OracleException.HandleError(OracleTraceLevel level, OracleTraceTag tag, Exception ex)
   at OracleInternal.TTC.TTCExecuteSql.ReceiveExecuteResponse(Accessor[]& defineAccessors, Accessor[] bindAccessors, Boolean bHasReturningParams, SQLMetaData& sqlMetaData, SqlStatementType statementType, Int64 noOfRowsFetchedLastTime, Int32 noOfRowsToFetch, Int32& noOfRowsFetched, Int64& queryId, Int32 longFetchSize, Int32 initialLOBFetchSize, Int64[] scnFromExecution, BindDirection[]& bindDirections, DataUnmarshaller& dataUnmarshaller)
   at OracleInternal.ServiceObjects.OracleCommandImpl.ExecuteReader(String commandText, OracleParameterCollection paramColl, CommandType commandType, OracleConnectionImpl connectionImpl, OracleDataReaderImpl& rdrImpl, Int32 longFetchSize, Int32 lobPrefetchSize, OracleDependencyImpl orclDependencyImpl, Int64[] scnForExecution, Int64[]& scnFromExecution, OracleParameterCollection& bindByPositionParamColl, Boolean& bBindParamPresent, Boolean isEFSelectStatement)
   at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior)
   at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteReader()
[...my code beyond this point...]

I have considered doing a Wireshark session to see what actually happens on the network level once this problem appears, but at the moment I don't really know what I am looking for, or what it tells me if I can find a failed connection to open a socket.

Anyone know what could cause this, and what can be done about it?

Huge thanks for any input!

c#
oracle
windows-services
asked on Stack Overflow Jun 17, 2013 by Rune Jacobsen

2 Answers

0

You should use "using" blocks to ensure resources are disposed in a timely fashion, even if an exception occurs. Try this first to see if it fixes the problem:

public bool CheckIfIdExists(string paramValue)
{
    var result = false;

    using (var conn = new OracleConnection(_connectionString))
    {
      conn.Open();
      using (var cmd = new OracleCommand("SQL query", conn))
      {
        cmd.CommandType = CommandType.Text
        cmd.Parameters.Add("paramName", paramValue);

        using (var rdr = cmd.ExecuteReader())
        {
          result = rdr.HasRows;
        }
      }
    }

    return result;
}
answered on Stack Overflow Jun 17, 2013 by Polyfun
0

I know this post is old, but I had the same problem a couple weeks ago. Even after insert the "using" statement in my code, the error still occurred. It was only after I created a better logging system, that I realized that the exception causing this error was this:

ORA-01033: ORACLE initialization or shutdown in progress

The best solution that I found was to treat this exception with a sleep of 5 minutes, so the oracle could restablish the connections again.


public void StartProcess()
{
    while(true) {
        try {
            //Everything the service does.
        }
        catch (Exception ex)
        {
              _serviceContainer.GetInstance<IErrorLogRepository>().Log(ex: ex);
              Thread.Sleep(300 * 1000);
         }
    }
}

answered on Stack Overflow Jul 12, 2019 by mvoelcker

User contributions licensed under CC BY-SA 3.0