Showing posts with label Oracle. Show all posts
Showing posts with label Oracle. Show all posts

Monday, June 23, 2014

How to configure webMethods JDBC Adapter to use Oracle RAC

If you have created a JDBC Adapter on WebMethods, it's a really straight forward process, but what happens when we have to connect to a Cluster

Try it and see what happens...

Now it's not that simple isn't?

Thankfully I have a workaround
  1. Leave blank serverName, databaseName and portNumber fields.
  2. In Other Properties enter your URL:
    url=jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)
    (ADDRESS=(PROTOCOL=TCP)(HOST=host1) (PORT=1521))
    (ADDRESS=(PROTOCOL=TCP)(HOST=host2) (PORT=1521))
    (CONNECT_DATA=(SERVICE_NAME=service)))
I hope this will help you.

Wednesday, April 23, 2014

Max number of values in IN clause

Somebody asked me about this a few days ago, and this person (really sure of what he was talking about) told me: "You can only pass a limit of 200 items in a IN clause (during a DELETE)"

I'm not an Expert DBA (know it all), but I do remember that you can pass up to 1000 elements. And that was my counter argument to this guy (as always if you don't believe me double check with your best friend or test it
In the past it used to be 256 elements, but that was in Oracle 8.

Saturday, April 13, 2013

Getting column info from Oracle table you don't own (without using describe)

How would one get columns information on table which he doesn't own, but has select granted? This is, without using DESCRIBE table_name

My answer is:

select owner, column_name from all_tab_columns where table_name = 'STUDENT';

Tuesday, February 8, 2011

Reading text files on MS-DOS

In my previous entry, I was trying to process a text files (a CSV), using each line of that file as input for my SQL*Plus call.
But, what happens if you don't have a UNIX box where you can execute it??? :(
Let's write my shell script into a batch file (oh man!), and this is the result: Where %%a is the first token, %%b the second one, and so on (until we'd reached the fourth token - as specified on tokens=1,2,3,4)
At the end, it was simple :D

Friday, February 4, 2011

Report in SQLPlus using spool to write a file

On my previous entry I'm reading a file and using each line as input to make an external call (call SQL*Plus for example) Well, this is my SQL (script) to be executed using SQL*Plus, in other words, I will execute this query for each line of a given file (shell script), each time that I call SQLPlus I'll append to the spool (output file) the result of my query (I'll pass as parameter to my query the parameter given on command call)
sqlplus CIDB/CIDB1234@CIDB @input_file.sql PRE11221000001

And this is my Query (my report, because I'm adding more stuff)
&&1
is the first parameter after the script namde in command line, then the second param will be &&2 then the third one &&3 and so on

My output will be a file named: output_file_2011-02-04.LST

For more information and references please see the official Oracle web site for SQL*Plus:
Ref 1
Ref 2
Ref 3
Ref 4

Run a SQLPlus script and pass a parameter as input

Simple:

Then your script:
begin dbms_output.put_line(&&1);
dbms_output.put_line(&&2);
end;
/

Thursday, December 2, 2010

Quest Toad on Oracle 11g not supported

Are you already on Oracle Database 11g?

Nevertheless, this post is to warn all developers out there using Quest TOAD for Oracle.
The current release of TOAD is 9.1, this version is not supported with Oracle 11g (client). But even more important, the version that comes out half of November, TOAD 9.5 (see screenshot below which is a beta), isn't working with the Oracle 11g client neither!
And looking around I found this message coming from Quest: Unfortunately, it was confirmed by our team's technical lead that Toad version 9.5 only support Oracle server 11g and not Oracle client 11g. My only suggestion for you is to install another client on your machine that is 10gR2 version or lower."

It's hard to believe that you need to install an Oracle Server just to get your development environment (TOAD) running ;-) Nevertheless, a workaround is to install Oracle 10g client, which I don't want to do as I'm connecting to 11g databases.
Or go for SQL Developer, a free alternative of Oracle.

A screenshot of the error "OCI version 11.1.0.1.0 is not supported"

Mendigos Oracle y TOAD!!!
I'm using both SQL Developer and TOAD as I think both have strengths and points to improve.
This post isn't to favor for SQL Developer, it's just to warn you.

Thursday, November 11, 2010

Conditions in One Line

Interesting point, how can I do 1 LINE If statements like in Java: This is the answer: I'll see on resultset cidb_order_id, 1 or 0 (segun sea el caso) The same sentence could be used on UPDATES:

Wednesday, October 27, 2010

My first official LEFT JOIN

When I was at school I always was afraid of using LEFT OR RIGHT Joins, well, almost 6 years after I'm done with school, I had to do my first one:

Tuesday, October 26, 2010

Add new parameter to Stored Procedure without impacting existing call

I have a Stored procedure already deployed in a production box, there is another porcess which wants to use it in a batch process, but the main batch process wants to control the transaction (commit/rollback). What can I do??
Add another parameter to my SP to handle the transaction or not, but If I do this the signature (DDL) of my SP is going to change!
There is one way to do this, something like adding polymorphism, on this case overload SP.
This is my original SP: On my iBatis side I'm calling this SP with this number of Params (5), If I add a new param, I'll have to add a new one to my DDL, right?
Not necessarily, because If you add another parameter but you don't declare it as IN neither OUT, it will be optional!!!
Then I can do this: And nobody will notice that I change it, because you can call it with 5 params (The 6th param will be given by default in the signature: DEFAULT 1) or with 6 (assigning 0 for example to the 6th parameter)
Inside the body of my SP I'm doing something like this:

Set Timeout when accessing Oracle with iBatis

Scenario:
There is a call which takes too much time, we don't want to wait until it's done, so in this case we can timeout our transaction and kill it on the Oracle side (well we don't kill/stop anything, we just abandon the process without any adverse impact);
Then we'll receive something like this from the DB:
ORA-01013: user requested cancel of current operation
How do you do that??
According to iBatis documentation, we can do it globally or for each statement/call we make by changing the value of defaultStatementTimeout
defaultStatementTimeout This setting is an integer value that will be applied as the JDBC query timeout for all statements. This value can be overridden with the “statement” attribute of any mapped statement. If not specified, no query timeout will be set unless specified on the “statement” attribute of a mapped statement. The specified value is the number of seconds the driver will wait for a statement to finish. Note that not all drivers support this setting.

Or we can do it Specifically for each statement element by setting the attribute timeout, for example:

Thursday, October 14, 2010

Create List of STRUCT based on a Query

This is my problem: I have a Stored Procedure which receives as parameter a List of Objects, this is my object

In Oracle to create a new instance of this kind of object, the default Contructor is given by definition of the object, for example in this case to create a new instance of CUST_ACCNT_MTN_PRE_ORDER, my contructor will be something like this
And this is my Collection/List/Table of Objects

My SP is something like this (As you'll see I'm using the same objects I defined in that entry)

And my solution is something like this
The secret is in this line: SELECT CUST_ACCNT_MTN_PRE_ORDER(CUST_ID, ACCT_NUM, NPA || NXX || TLN, -1, 'X', MTN_ORDER_TYPE, SYSDATE, NVL(EO_ALT_NPA||EO_ALT_NXX||EO_ALT_TLN,0)) BULK COLLECT INTO p_list
I'm creating for each row an object of type CUST_ACCNT_MTN_PRE_ORDER and then the ResultSet is set INTO p_list variable using BULK COLLECT, which fetch all rows once


IF you want to see my Stored Proc, this is what I did
CREATE OR REPLACE PROCEDURE record_ship_temp_orders(   
 out_orders_processed   OUT   NUMBER
)
IS
my_cust_id    CUST_ACCT_ORDER.cust_id%TYPE; 
my_acct_num    CUST_ACCT_ORDER.acct_num%TYPE;
my_pos_order_id    CUST_ACCT_ORDER.pos_order_id%TYPE;
my_pos_pre_order_id    CUST_ACCT_ORDER.pos_pre_order_id%TYPE;
my_pos_loc_cd    CUST_ACCT_ORDER.pos_loc_cd%TYPE;
my_total_order_lines    CUST_ACCT_ORDER.total_order_lines%TYPE;
my_ord_add_lines_cnt    CUST_ACCT_ORDER.add_lines_cnt%TYPE;   
my_ord_upg_lines_cnt    CUST_ACCT_ORDER.upg_lines_cnt%TYPE;  
p_list  CUST_ACCNT_MTN_PRE_ORDER_LIST; 
OUT_CIDB_ORDER_ID NUMBER;

--This is the main cursor 
CURSOR cur_test_init_load
    IS
    SELECT CUST_ID_NO AS CUST_ID, 
            ACCT_NO AS ACCT_NUM, 
            EQ_ORD_NO AS POS_ORDER_ID, 
            NULL AS POS_PRE_ORDER_ID, 
            NETACE_LOC_ID AS POS_LOC_CD             
    FROM TEST_INIT_LOAD
    GROUP BY CUST_ID_NO, ACCT_NO, EQ_ORD_NO, NULL, NETACE_LOC_ID
    ORDER BY CUST_ID_NO, ACCT_NO, EQ_ORD_NO, NETACE_LOC_ID;
    
/******************************************************************************
   NAME:    record_ship_temp_orders
   PURPOSE:    Retrieve data loaded into TEST_INIT_LOAD to be processed by
     Record_Pre_Order and then shipped by Ship_Pre_Order.
   DATE:    Oct 2010
   Referenced by:    To be executed internally

******************************************************************************/    
    
BEGIN 
DBMS_OUTPUT.put_line('Starting prcess '||TO_CHAR(SYSTIMESTAMP,'hh:mi:ss.FF'));
OPEN cur_test_init_load;  
        IF cur_test_init_load%NOTFOUND THEN         
  DBMS_OUTPUT.put_line('No data found on TEST_INIT_LOAD');   
  CLOSE cur_test_init_load;
  raise_application_error(-20102, 'No data found on TEST_INIT_LOAD');
 END IF; 
 
 out_orders_processed := cur_test_init_load%ROWCOUNT; --Before the first fetch, %ROWCOUNT returns 0
 
 DBMS_OUTPUT.put_line('Start record '||TO_CHAR(SYSTIMESTAMP,'hh:mi:ss.FF'));
 LOOP --Iterate cursor
 FETCH cur_test_init_load INTO my_cust_id, my_acct_num, my_pos_order_id, my_pos_pre_order_id, my_pos_loc_cd;
 
 IF out_orders_processed = 0 THEN
  out_orders_processed := cur_test_init_load%ROWCOUNT; --Set a value to the OUT param
 END IF;
 
 EXIT WHEN cur_test_init_load%NOTFOUND;--Exits when process is completed

 DBMS_OUTPUT.put_line('Processing  '||my_cust_id||'-'||my_acct_num||', my_pos_order_id='||my_pos_order_id||', my_pos_pre_order_id='||my_pos_pre_order_id||', my_pos_loc_cd='||my_pos_loc_cd);
 
  --Calculate total_order_lines, add_lines_cnt & upg_lines_cnt
            SELECT count(1) AS TOTAL_ODER_LINES INTO my_total_order_lines
            FROM TEST_INIT_LOAD
            WHERE CUST_ID_NO = my_cust_id
              AND ACCT_NO =  my_acct_num
              AND EQ_ORD_NO = my_pos_order_id;
              
            SELECT count(1) AS ADD_LINES_CNT INTO my_ord_add_lines_cnt
            FROM TEST_INIT_LOAD
            WHERE CUST_ID_NO = my_cust_id
              AND ACCT_NO =  my_acct_num
              AND EQ_ORD_NO = my_pos_order_id
              AND ESN_CHG_RSN_CD IS NULL;
  
            SELECT count(1) AS UPG_LINES_CNT INTO my_ord_upg_lines_cnt
            FROM TEST_INIT_LOAD
            WHERE CUST_ID_NO = my_cust_id
              AND ACCT_NO =  my_acct_num
              AND EQ_ORD_NO = my_pos_order_id
              AND ESN_CHG_RSN_CD IS NOT NULL;
              

 DBMS_OUTPUT.put_line('my_total_order_lines  '||my_total_order_lines||', my_ord_add_lines_cnt='||my_ord_add_lines_cnt||', my_ord_upg_lines_cnt='||my_ord_upg_lines_cnt);
              
               --Generate List of Items to be inserted into CUST_ACCT_MTN_ORDER
            SELECT CUST_ACCNT_MTN_PRE_ORDER(CUST_ID, ACCT_NUM, NPA || NXX || TLN, -1, 'X', MTN_ORDER_TYPE, SYSDATE, NVL(EO_ALT_NPA||EO_ALT_NXX||EO_ALT_TLN,0)) BULK COLLECT INTO p_list
            FROM (  
                SELECT CUST_ID_NO AS CUST_ID, 
                            ACCT_NO AS ACCT_NUM,
                            NPA , NXX , TLN,
                            NVL(ESN_CHG_RSN_CD,'A') AS MTN_ORDER_TYPE,
                            EO_ALT_NPA,EO_ALT_NXX,EO_ALT_TLN 
                FROM TEST_INIT_LOAD
                WHERE CUST_ID_NO = my_cust_id
                  AND ACCT_NO =  my_acct_num
                  AND EQ_ORD_NO = my_pos_order_id
                  AND ESN_CHG_RSN_CD IS NULL
  
                  UNION
  
                SELECT CUST_ID_NO AS CUST_ID, 
                            ACCT_NO AS ACCT_NUM,
                            NPA , NXX , TLN,
                            'U' AS MTN_ORDER_TYPE,
                            EO_ALT_NPA,EO_ALT_NXX,EO_ALT_TLN
                FROM TEST_INIT_LOAD
                WHERE CUST_ID_NO = my_cust_id
                  AND ACCT_NO =  my_acct_num
                  AND EQ_ORD_NO = my_pos_order_id 
                  AND ESN_CHG_RSN_CD IS NOT NULL    
            ); 
            
     FOR i in 1 .. p_list.count
     LOOP
  DBMS_OUTPUT.put_line ('STRUCT '||i||'=> mtn='||p_list(i).mtn||', mtn_order_type='||p_list(i).mtn_order_type||', bdy_mtn='||p_list(i).bdy_mtn);
     END LOOP;  
     --Call SP's
      BEGIN 
   DBMS_OUTPUT.put_line('Calling Record_Pre_Order');
   RECORD_PRE_ORDER ( my_cust_id, my_acct_num, my_pos_order_id, my_pos_pre_order_id, my_pos_loc_cd, my_total_order_lines, my_ord_add_lines_cnt, my_ord_upg_lines_cnt, 0, p_list, OUT_CIDB_ORDER_ID );
   DBMS_OUTPUT.put_line('Calling Ship_Pre_Order');
   SHIP_PRE_ORDER ( my_cust_id, my_acct_num, my_pos_order_id, my_pos_loc_cd, OUT_CIDB_ORDER_ID ); 
   DBMS_OUTPUT.put_line('End record '||TO_CHAR(SYSTIMESTAMP,'hh:mi:ss.FF'));
   DBMS_OUTPUT.put_line('-------');
   p_list := NULL;
  EXCEPTION
      WHEN OTHERS
      THEN
      DBMS_OUTPUT.put_line ('***ERROR*** '||SQLERRM);
      out_orders_processed := out_orders_processed - 1; --Decrease failed orders
  END;
 END LOOP; 
DBMS_OUTPUT.put_line('Process completed');
DBMS_OUTPUT.put_line('End of process '||TO_CHAR(SYSTIMESTAMP,'hh:mi:ss.FF'));
CLOSE cur_test_init_load;
 
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line (SQLERRM);
      ROLLBACK;
      RAISE;
END;
/

Thursday, September 30, 2010

Validation Query on WebSphere DataSource

Do you remember this?? (for those who have worked before with DBCP : validationQuery)

I was tired to look for this attribute in Websphere and I found it :P


Tip: On DB2 the equivalent to SELECT 1 FROM DUAL is SELECT 1 FROM SYSIBM.SYSDUMMY1

Monday, September 20, 2010

Pass Collection of Objects with Attributes to a Stored Procedure using iBatis

In my last entry I had a requirement which needed to pass a List to an Oracle Stored Procedure, well, that thing is history.
But now the problem becomes more complex, because, what happen if I'm expecting on my Stored Proc and Type (STRUCT)
This is my Collection in Oracle!
And this is my Stored Proc (this is just a sample which receives the TABLE of Records)
This is the table where I'm going to INSERT
Obviously, the solution is Create a Handler like I did on my last entry, but is not going to be as simple, because I need to Map my Oracle STRUCT with my Java Code, so I have to do an domain object (POJO) coupled to Oracle and my Handler.
Once we have our Mapper class, then let's do the Handler!!!
And this is how it looks my Map (XML)

In case you have to receive the Array from your Stored Proc, you just have to write in your Handler somethig like this:

References: Using iBatis with a stored function returning a Collection Type and Oracle UDT Collections as IN and OUT parameters with iBatis

Friday, September 17, 2010

Pass Collection to Stored Procedure using iBatis

Today I had a really crazy idea: "Why not making my query work with a list of parameters like I do with Hibernate using the operator IN???"
It sounds simple, Isn't it??? Ok, then try to do it with an Stored Procedure in Oracle :P
Then, this is my Stored Proc (I had to create a Type to have support for Arrays in Oracle, because an Array is not a simple-provided data type): As you can see, my dear visitor, I'm expecting some simple parameters and I'm returning a ResultSet, really straight forward, but the problem comes with the Array of NUMBER (that's why I created my
TYPE NUMBER_ARRAY AS TABLE OF NUMBER
)

The solution to this problem is easier than it seems, just create a Handler dude!!! The magic begins when I transform the Connection (because I have to work at the connection level) provided by the Application Server (WebSphere on this case - If this happens to me on another App Server or with another Connection Pool, I'm going to be in trouble, because the issue will be how to retrieve a Native java.sql.Connection, but that will be another story).
Let's analyze this monster:
* Get Native Connection
*Create my ArrayDescriptor for my Type (these NUMBER_ARRAY is my TYPE I created previously)
*Create my parameter, an ARRAY (al fin y al cabo) and we're set!

Finally this is my mapping file for my stored procedure

And my code lived happily ever after!!! Abur!!!

Friday, September 10, 2010

JDBC url for oracle RAC

If you have to connect to oracle RAC (Real Application Cluster) using JDBC with thin driver, the classic url:
jdbc:oracle:thin:@<HOST>:1521:<SID>
doesn’t work and you get the error ORA – 12505.
Instead, you must use this url:
jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)
(ADDRESS=(PROTOCOL=TCP)(HOST=host1) (PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=host2) (PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=service)))
If you have an oracle client, like toad, check the tsnames.ora for the correct values of SERVICE_NAME and host.

Wednesday, September 17, 2008

JDBC url for oracle RAC

If you have to connect to oracle RAC (Real Application Cluster) using JDBC with thin driver, the classic url:
jdbc:oracle:thin:@<HOST>:1521:<SID>
doesn’t work and you get the error ORA – 12505.
Instead, you must use this url:
jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)
(ADDRESS=(PROTOCOL=TCP)(HOST=host1) (PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=host2) (PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=service)))
If you have an oracle client, like toad, check the tsnames.ora for the correct values of SERVICE_NAME and host.

Sunday, June 22, 2008

Firewall dropping Oracle connections in WebSphere Connection Pool?

We recently switched one of our client’s WebSphere Application Server and WebSphere Portal based infrastructure to a new physical environment. During our testing we found that we were getting stale connection exceptions in SystemOut.log and in the application logs.
On digging a little deeper, our team tracked it down to the fact that the Cisco firewall was dropping our Oracle database connections after they had been inactive for a certain amount of time.
When our team discussed the issue with the network team, they were essentially told that all was good with the network infrastructure.
The application team tweaked some of the connection pool settings but that only helped alleviate the issue slightly and we started encountering performance issues. Eventually, we figured out a solution that works!

The solution that we ended up with was to work around this issue on the Oracle end. We modified the sqlnet.expire_time parameter in sqlnet.ora on the Oracle 10g server down from the default “30″ (30 minutes) to “1″ (1 minute).

Why this worked?
The parameter SQLNET.EXPIRE_TIME is used to specify the time interval, in minutes, to send a probe to verify that client/server connections are active. If the probe finds a terminated connection, or a connection that is no longer in use, it returns an error, causing the server process to exit. This parameter is primarily intended for the database server so that it can free up server-side resources that are not in use.
A side-effect of the probe is that there is TCP-IP activity between the client and the server each time the probe is executed, and the firewall designates the link as an active one. By lowering the probe interval down to a minute, we managed to fool the firewall into leaving the database connections in the connection pool alone, and not terminate them even though the client may not execute a query using the connection for an extended period of time.
I am sure you can tweak the value of this parameter to determine the optimal value for your firewall and situation; dropping down the sqlnet.expire_time to a minute is probably too radical and redundant in reality. Even though the probe generated by this setting is small, it still does generate network traffic that may be meaningful in some situations.

Sunday, May 11, 2008

The mysterious ORA-03111 error

Recently one of the applications that I developed started throwing exceptions, that had the following message:
SQL state [72000]; error code [1013]; ORA-03111: break received on communication channel
When I googled around, I couldn't come across anything useful. Sadly enough most of the sites just showed the documentation for that error, without any explanation from anyone experiencing that issues. So here you go, with the best possible explanation that I could come up with.

My application sets two things on the connection that is throwing this exception:
  • It sets the fetchSize to be 2500 rows
  • It sets the query timeout to be 10 seconds
The database server and the application are separated over a long latency network (actually there is a NetEm box that emulates the long latency between these two boxes) which has a latency characteristic of 50+/-5 milliseconds. This is the whole setup.

It is important to understand how the timeout is handled by the Oracle client (in my case JDBC client). Once the query is successfully submitted, the client starts a clock for the timeout. Once the timeout is reached, the client sends an URG message to the Oracle server. The moment Oracle server receives this message, it knows that the client wants to cancel the operation that it was carrying on, no matter what stage the operation is in.

So take a couple of cases. Assume the operation is a SELECT query that will result in 10000 rows. If the Oracle server hasn't even started fetching the results, most likely the client's request would be responded immediately with an error code ORA-01013, which has a description like:
SQL state [72000]; error code [1013]; ORA-01013: user requested cancel of current operation
But imagine the server has fetched the rows and in the process of pumping the resultset back to the client. If the client requests the Oracle server to cancel the operation while still there is pending data in the socket to be delivered, it just adds the ORA-03111 packet at the end of the pending packets and lets the client knows that the operation has been cancelled while there is pending data to be delivered.

Look at the tcpdump output below:
23:13:08.613007 IP jdbc_client.48681 > orcle_server.1521: P 2543:3174(631) ack 2342 win 11908
....
23:13:18.635068 IP jdbc_client.48681 > orcle_server.1521: P 3174:3175(1) ack 265693 win 65535 urg 1
....
23:13:20.472561 IP orcle_server.1521 > jdbc_client.48681: P 398520:398615(95) ack 3186 win 65535
0x0000: 0015 c5ec 12a8 0021 1c1d c0c3 0800 4500 .......!......E.
0x0010: 0087 5023 0000 3406 bad6 c0a8 fd9a c0a8 ..P#..4.........
0x0020: fc8b 05f1 be29 a792 459f a091 06cc 5018 .....)..E.....P.
0x0030: ffff 67c2 0000 005f 0000 0600 0000 0000 ..g...._........
0x0040: 0402 04e3 0203 f500 0001 0300 0300 0000 ................
0x0050: 0000 0000 0000 0000 0000 0001 0100 0000 ................
0x0060: 0033 4f52 412d 3033 3131 313a 2062 7265 .3ORA-03111:.bre
0x0070: 616b 2072 6563 6569 7665 6420 6f6e 2063 ak.received.on.c
0x0080: 6f6d 6d75 6e69 6361 7469 6f6e 2063 6861 ommunication.cha
0x0090: 6e6e 656c 0a nnel.

Pay special attention to the times when the SELECT query was sent (21:13:08) and when the cancel request as an URG packet was sent (21:13:18), and when the Oracle sends the last TNS packet that has the error code ORA-03111 (21:13:20).

The cancel request as an URG packet was sent after 10 seconds because as I mentioned earlier my query timeout is 10 seconds.

So now the million dollar question: What should I do if I am facing this issue in my application?

Follow these simple steps:
  • First make sure that your query can be completed within the timeout that you have specified. If you consistently face this exception, try increasing your timeout.
  • That might help to get rid of the exception, but not the root cause. The root cause usually is a database that is not optimized for the query that you are executing or a bad network.
  • To find out if its the database that is the issue, try executing the same query in a host closer to the network. Or try executing the same query hitting the database from a different network. If you are convinced the database is the issue, try to tune it.
  • To find if it is the network that is having the issue, try to do a tcpdump and analyze if there are any out of order deliver of packets. Or dropped packets. If yes, then try to fix the network.
In my case, it turned out to be the bad configuration in the NetEm that was causing too many packets to be delivered out of order and too many duplicated packets. Remember I was introducing a variance of 10 ms (i.e. my packets could be delayed anywhere from 45 ms to 55 ms, as per my configuration). In real cases, at least in a well maintained production network, the variance will not be more than 1 ms.
If by any chance: "algun Oracle Expert se apiada de mi" your collaboration will be greately appreciate it.