On 02/11/2012 11:46, John Scoles wrote:
> Boy I think I really started something here.
>
> I just heard back from OIC connection over at Oracle and here is his two cents on the issue
>
> "From an OCI point of view the OCIPing/OCIServerVersion calls are as
> good as it gets for basic aliveness of the connection. I'd never have
> thought they would guarantee the DB was writable. I believe they just
> check the OCI and Network stacks. Since the connection doesn't know
> anything about DB privileges or what action might be attempted on the
> connection, I don't think the calls could do more. Also by the time
> an application does execute some SQL, the the
> connection/node/server/network could have dropped and so the application
> 'will have to check & recover from write failures at that point anyway."
>
> So OCIPing and OCIServerVersion do the same thing and yes they 'Do not check that a query can be executed'
Thinking about it, wrt executing a query or inserting/updating/deleting
it cannot be full proof anyway as things can change after you called
OCIPing/OCIServerVersion. From the point of DBI, the ping method is
mostly used to indicate the connection is dead (ODBC has something
similar in SQL_ATTR_CONNECTION_DEAD). If ping returns false a cached
connection has to be renewed. If ping returns true a cached connection
is not dead at the point ping was called but might not work thereafter.
The replacement in DBIx::Connector which issues a select is better (in
Oracle's case than DBD::Oracle's ping) but still could suffer from
something changing in Oracle server since the "select 1 from dual"
returned ok.
It is a race condition - there is no absolute solution in this case. So,
we can rely on ping (or select 1 from dual) returning false but not on
it returning true.
> As for history of Ping in DBD::Oracle
>
> All version up till 1.21 use a query with a do
> 1.22 till 1.24 use just OCIServerversion
> 1.25 and later use either OICPing or OCIServerversion depending on the Oracle client.
>
> I think in the case of DBIx::Connector you want to really 100% know that a connection can execute a Query?
but as explained above, I doubt you can 100% - there is a period of time
elapsing from checking and doing.
> The DBI doc sort of implies that but I checked a few other DBD and I see that DBD::Pg uses an 'select' and Mysql has 'mysql_ping' the same sort of thing as OCIPing except it can reconnect.
>
> So For three DBDs you may see three separate behavours for DBH->ping
Live with it - I doubt you'll get much better in DBD::Oracle and
certainly not across DBDs. You should however, be able to rely on ping
returning false. Perhaps the DBI docs should be updated to explain this
better.
> 1) working but a zombie
> 2) error
> 3) reconnection, error or a zombie
>
> So perhaps we need
>
> 1) A clarification on what DBH->ping does or is suppose to do (Tim Jump in)
> 2) A if DBH->Ping really means I can run a query a change to DBD::Oracle
and I doubt such a change is possible.
>
> 3) Perhaps a new method like dbd->can_query??
which will still suffer from a race condition.
> David if you have a repeatable test or set of conditions or recipe of how you get into this state where DBD::Oracle pings but cannot run queries my buddies over at Oracle would love to get it.
>
> Cheers
> John
Probably not what you want to hear but it is the way it is.
Apologies for not giving this sufficient thought in my last reply - bad
day all round on my part.
Martin
> ----------------------------------------
>> Date: Fri, 2 Nov 2012 09:59:30 +0000
>> From:
martin...@easysoft.com
>> To:
da...@justatheory.com
>> CC:
dbi...@perl.org
>> Subject: Re: Oracle ping