Reputation: 460
We are using a Lumen 5.2.x (Laravel) application to get data from a Oracle Database. For that reason we use oci_connect()
to connect to the database. (Extra info: we use Oracle instantclient)
For a reason unknown, the application was not responsive and wouldn't return any data. After lots of hours debugging we found out that it got stuck in that very same method: oci_connect()
. Apparently the function did not return a 'time-out'-message or anything similar.
Later, it seemed the database moved to another host, which is the reason it couldn't connect. However, we expected a error, instead of a huge amount of waiting.
This is the reason we are trying to force a time-out to be set, until now this has not worked out.
Things we have tried:
Adding this to the connection string: (CONNECT_TIMEOUT=10)(RETRY_COUNT=3)
which is completely ignored.
Setting max_execution_time
and set_time_limit
to 1
Adding a sqlnet.ora
with settings:
TCP.CONNECT_TIMEOUT=10
SQLNET.INBOUND_CONNECT_TIMEOUT=10
SQLNET.OUTBOUND_CONNECT_TIMEOUT=10
Everything we have tried failed, does anyone know how to work around this bug? Any help is appreciated!
Edit: System info: Windows Server 2012 R2, IIS 8, PHP 5.6
Upvotes: 5
Views: 2806
Reputation: 659
From the docs:
"Sometimes Oracle doesn't cleanup shadow processes when accessed from PHP. To avoid that, check your $ORACLE_HOME/network/admin/tnsnames.ora file in your Oracle Client directory and remove the (SERVER=DEDICATED) token if is set.
To let Oracle delete shadow process on timeouts, add the following line in your
$ORACLE_HOME/network/admin/sqlnet.ora
found in your ORACLE Server directory:
SQLNET.EXPIRE_TIME=n
Where 'n' is the number of minutes to let connection idle befor shutting them out."
Have you tried this?
Upvotes: 0
Reputation: 2080
Unfortunately, oci_connect
is already too high-level a function to allow timeout control - OSI model layer 5, if you consider it is there to establish a session for what follows. I suggest you try fsockopen
on port 1521, level 4, which 5th argument sets the timeout in seconds. If fsockopen() returns a valid resource, then proceed with oci_connect(), otherwise report error / throw exception.
I checked it today, part of a "preflight assessment" when establishing four Oracle connections with various remote sites. It actually gives up after timeout seconds!
Upvotes: 1
Reputation: 59
I copied the oracle array from oracle.php to the database.php config file and the issue has gone away.
Contents of my oracle.php file:
return [
'oracle' => [
'driver' => 'oracle',
'tns' => env('DB_TNS', ''),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1521'),
'database' => env('DB_DATABASE', ''),
'username' => env('DB_USERNAME', ''),
'password' => env('DB_PASSWORD', ''),
'charset' => env('DB_CHARSET', 'AL32UTF8'),
'prefix' => env('DB_PREFIX', ''),
],
];
Upvotes: 1
Reputation: 5303
You have tried several approach, which is great. The max_execution_time
is a good one. You can register a shutdown function so that you can log the error if any - or do whatever you need.
<?php
function shutdown(){
$error=error_get_last();
if(is_null($error))
echo "No errors"; //or do nothing
else
print_r($a); //or log it properly
}
register_shutdown_function('shutdown');
ini_set('max_execution_time',3 );//max 3 seconds
sleep(5); //just for test it out
In any case, according to the web (for instance : "don't loose your head, move to Linux"), you should try using Linux to run your webserver when working with Oracle connection, if possible).
(I know that there were, at some time, a lot of rage between Linux and Windows People. But if operating system is more suited for some use case, why bother using the other)
Upvotes: 0