I have an application running on Oracle 10g using Hibernate. I am wondering if it is possible to make the application highly available with respect to database failures without any code changes on the application side, using Oracle RAC.
I have two Oracle RAC nodes for the application, and ideally would like to be able to pull the plug on one of the nodes and have the application continue to run, without any exceptions reaching the application code.
My application sends select, insert, update and delete queries to the database.
I have been reading about Transparent Application Failover, but the sites I have found imply that only select queries can be failed over transparently, and that all other types of queries will result in exceptions being thrown and the query having to be re-executed. I would rather avoid this as I do not want to add extra exception handling to every part of my code base which makes database queries.
Sorry, but not really. You're looking at Transparent Application Failover (TAF) and Oracle doesn't currently support TAF for anything but SELECT statements. DML will need to be restarted. Take a look at this article for a good explanation of what RAC (and TAF) can do for you.
No matter what, you're going to need to be able to handle transaction failures. That's a big reason why we have transactions... so we can handle things failing gracefully. Realize, as well, that hardware failure (what RAC protects you against) is only one of a myriad of reasons a transaction may fail.
Good luck, happy coding!
Related
My VB6 program uses ADODB to do a lot of SQL (2000) CRUD.
Sometimes the network connection between the remote clients and the data center somehow "drops" resulting in the impossibility to establish new connections (so users launching the program can't use it).
The issue is the following:
Anyone who is using the program at the moment of the "drop" can continue using it with no issues whatoever, perform every operation, update data, read data, and everything seems like is working normally.
User then proceeds to fire up a "sum-up" report which lists everything that was done (before or after the "drop").
If we then check the database, all data regarding whatever was done after the network drop is not there. User goes back into the program and everything is as it was before the network drop.
It seems like all queries where somehow performed in-memory ? I'm at a loss about how to even approach the issue (I'm familiar enough with VB6 to work with the source code but I don't know a lot about ADODB).
I haven't yet tried to replicate the behavior due to limited customer's availability (development environment is housed in their offices), I'll try starting up the program from the IDE then rip out the network cable.
Provided I can replicate the issue, how do I fix this ? Is there some setting I'm not aware of ?
On a side note: the issue is sporadic (it happened a handful of times during the last year, and the software is being used heavily and on a daily basis by mutiple concurrent users).
After reading up on Disconnected Recordsets, it seems that's what's behind this odd behavior I'm experiencing.
This is not something that can be simply "turned off".
I'm using Spring with Hibernate. I have some queries that don't actually need a transaction, but I'm using one because it does the session management for me. What is the correct way of doing these non-transactional read queries without doing my own session management?
I think #Transaction(readOnly=true) is the right way to do it. That's not going to create a new/extra physical transaction, so there shouldn't be any overhead to using that. It's going to use the transaction that was already set up for the request. Per the Hibernate docs:
... in fact, every SQL statement, be it queries or DML, has to execute inside a database transaction. There can be no communication with a database outside of a database transaction. (Note that there are such things as read-only transactions, that can be used to improve cleanup time in a database engine if it is not smart enough to optimize its own operations.)
https://community.jboss.org/wiki/SessionsAndTransactions#Transactions
There is no way you can work without transactions with database (well, there is, but it's a rare case that driver supports NO_TRANSACTION mode like DB2 driver). Moreover, drivers and databases may not support read-only transactions (like Oracle). So even if underlying connection was set to read-only mode, this doesn't mean it will have effect.
The only thing that is for sure about read-only flag in this case is that it will set Hibernate's flush mode to MANUAL. This means that Hibernate won't synchronize with database unless explicit call to Session#flush() was issued. So no dirty checks and no inserts/updates/selects will be issued in the end of transaction.
For more precise information on transaction management you can take a look at org.springframework.orm.hibernate3.HibernateTransactionManager#doBegin() method.
My application have performance issues, so i started to investigate this from the root: "The connection with the database".
The best practices says: "Open a connection, use it and close is as soon as possible", but i dont know the overhead that this causes, so the question is:
1 -"Open, Use, Close connections as soon as possible is the best aproach using ODP.NET?"
2 - Is there a way and how to use connection pooling with ODP.NET?
I thinking about to create a List to store some connections strings and create a logic to choose the "best" connection every time i need. Is this the best way to do it?
Here is a slide deck containing Oracle's recommended best practices:
http://www.oracle.com/technetwork/topics/dotnet/ow2011-bp-performance-deploy-dotnet-518050.pdf
You automatically get a connection pool when you create an OracleConnection. For most middle tier applications you will want to take advantage of that. You will also want to tune your pool for a realistic workload by turning on Performance Counters in the registry.
Please see the ODP.NET online help for details on connection pooling. Pool settings are added to the connection string.
Another issue people run into a lot with OracleConnections is that the garbage collector does not realize how truly resource intensive they are and does not clean them up promptly. This is compounded by the fact that ODP.NET is not fully managed and so some resources are hidden from the garbage collector. Hence the best practice is to Close() AND Dispose() all Oracle ODP.NET objects (including OracleConnection) to force them to be cleaned up.
This particular issue will be mitigated in Oracle's fully managed provider (a beta will be out shortly)
(EDIT: ODP.NET, Managed Driver is now available.)
Christian Shay
Oracle
The ODP.NET is a data provider for ADO.NET.
The best practice for ADO.Net is Open, Get Data (to memory), close, use in memory data.
For example using a OracleDataReader to load data in a DataTable in memory and close connection.
[]'s
For a single transaction this is best but for multiple transaction where you commit at the end this might not be the best solution. You need to keep the connection open until the transaction either committed or rolled back. How do you manage that and also how do you check the connection still exist in that case?(ie network failure) There is ConnectionState.Broken property which does not work at this point.
I have a third party Windows service which controls/monitors equipment and updates an Oracle database. Their services occasionally report an error about a row/column in the database being "bad" but do not give the underlying database error, and their services need to be restarted and everything is fine. The current suspicion is that something from our applications/services which read/write to those same tables/rows are interfering - i.e. some kind of blocking/locking. I suspect that there is some sort of leak in their system since it happens about once a week, but our systems never need any re-starting like this.
I attempted to have the DBA run a trace run in Oracle (10g), but this managed to make our apps unable to access the Oracle database. Our systems access Oracle in .NET, either using the Oracle ODP client or Microsoft client (older programs) and on this same server (either web apps or services) or from other control workstations. The third-party services connects to Oracle via ODBC on this server. I also attempted to run a ODBC trace (since that would only be activity from the third-party service), but didn't get anything in the trace file at all.
So I'm trying to find a way to either get ODBC tracing working or what I need to look out for so that the Oracle trace doesn't kill my server.
I'm looking for the undserlying error which Oracle is returning to the thrid-party service so I can tell if we are interfering with their access to the data in some way.
If a block in the database is corrupted "Bad" this should show up in the alert logs as an ORA-01578 error. I would search the archive log for the ORA- error and then compare that with the time stamp on the client error being reported. This is making the assumption of the definition of "Bad". It would be better to have the exact error messages posted.
Blanket tracing in the database is a tricky thing as it will tend to affect the performance of your entire application. And leaving it on for an entire week may not be feasible. I have also found in one case (cant remember the exact circumstance) where turning on tracing fixed the error.
One method I have used in the past is to add the sql statement to alter the session and turn on sqltrace. This is predicated on the ability to modify the code in some way. Depending on the application this may or may not be possible.
Another method would be to work with the DBA to identify the session and turn on sql trace for that session. Also if you can identify the offending sql statements and parameter values you may be able to replicate the problem outside the service.
I have found most ORM's avoid passing the ORA- error back. However it is typically logged in the application server layer with the associated ORM error.
I have used these method and variations of these method to trouble shoot errors in the application. I hope this is useful.
We have a JPA -> Hibernate -> Oracle setup, where we are only able to crank up to 22 transactions per seconds (two reads and one write per transaction). The CPU and disk and network are not bottlenecking.
Is there something I am missing? I wonder if there could be some sort of oracle imposed limit that the DBA's have applied?
Network is not the problem, as when I do raw reads on the table, i can do 2000 reads per second. The problem is clearly writes.
CPU is not the problem on the app server, the CPU is basically idling.
Disk is not the problem on the app server, the data is completely loaded into memory before the processing starts
Might be worth comparing performance with a different client technology (or even just a simple test using SQL*Plus) to see if you can beat this performance anyway - it may simply be an under-resourced or misconfigured database.
I'd also compare the results for SQLPlus running directly on the d/b server, to it running locally on whatever machine your Java code is running on (where it is communicating over SQLNet). This would confirm if the problem is below your Java tier.
To be honest there are so many layers between your JPA code and the database itself, diagnosing the cause is going to be fun . . . I recall one mysterious d/b performance problem resolved itself as a misconfigured network card - the DBAs were rightly insistent that the database wasn't showing any bottlenecks.
It sounds like the application is doing a transaction in a bit less than 0.05 seconds. If the SELECT and UPDATE statements are extracted from the app and run them by themselves, using SQL*Plus or some other tool, how long do they take, and if you add up the times for the statements do they come pretty near to 0.05? Where does the data come from that is used in the queries, and which eventually gets used in the UPDATE? It's entirely possible that the slowdown is not the database but somewhere else in the app, such a the data acquisition phase. Perhaps something like a profiler could be used to find out where the app is spending its time.
Share and enjoy.