I have an Oracle Package with some Global Variables which are initialized and used on all procedures of that package.
When I call the procedures (via jdbc connection and calls) the global variables are correctly initialized and their values persists through all procedures on the database session that was opened, but when I have multiple jdbc connections it seems that the global variables values are mixed between the calls.
Isn't Oracle sessions isolated in terms of packages variables? Is there some configuration that I need to do on the database or user profile to guarantee that isolation?
My DB Instance is in a RAC with 2 nodes.
Each database session has its own set of variables, yes.
I would expect that your Java application is using a connection pool such that your Java application is constantly getting connections from the pool and returning them to the pool. If that's the case, there is no relationship between a Java session and an Oracle session. A particular Java session might use Oracle session A for the first call, Oracle session B for the second call, C for the third call, and B again for the fourth call. And other sessions would be doing the same thing so the state of session B might have changed between the two calls because some other Java session used it in the interim.
Some connection pool implementations explicitly clear out package variables when a session is returned to the pool so that data doesn't leak from one session to another. Other implementations would allow the different Java sessions to see the package variables in whatever state they happen to be from the prior call. In either case, maintaining state in packages as part of an enterprise Java application is a bad idea.
It is possible that you want a global context instead but it's hard to know that for sure since we don't know what problem you're trying to solve with your package variables.
Related
I have a JBoss 6 application running both EJB and Spring code (some legacy involved in this decision). It should communicate to Oracle and PostgreSQL databases, on demand.
JPA is the way DB operations are done, no direct JDBC is involved.
I would like to do the following: without altering the business logic, to be able to "silence" database updates/deletes from my application, without breaking the flow with any exceptions.
My current thoughts are:
Set the JDBC driver as read-only from the deployment descriptor - this works only with PostgreSQL (Oracle driver does not support this)
Make a read-only user on the RDBMS level - it might fill me up with errors
Make all transactions rollback instead of committing - is this possible?
Make entity manager never persist anything - set the FlushMode to MANUAL and make sure flush() never gets called - but commit() still flushes everything.
Is there any other concise approach to this?
If you want to make sure the application works as on production, work on a replica of the Database. Use a scheduler every night that overwrites the replica DB.
My request also includes the need for this behavior to be activated or deactivated at runtime.
The solution I found (currently for a proof-of-concept) is:
create a new user, grant him rights on the default schema's tables;
with this user create views for each of the tables, with the same name (without the schema prefix);
create a trigger for each view that does nothing on insert, update, or delete, using INSTEAD OF;
create a data source and persistence unit for this user;
inject two entity managers at runtime, use the one that is needed;
Thanks for your help!
I have the following issue:
Two instances of an application on two different systems should share a small database.
The main problem is that both systems can only exchange data through a network-folder.
I don't have the possibilty to setup a database-server somewhere.
Is it possible to place a H2 database on the network-folder and let both instances connect to the database (also concurrently)?
I could connect with both instances to the db using the embedded mode if I disable the file-locking, right?
The instances can perfom either READ or INSERT operations on the db. Do I risk data corruptions using multiple concurrent embedded connections?
As the documentation says; ( http://h2database.com/html/features.html#auto_mixed_mode
)
Multiple processes can access the same database without having to start the server manually. To do that, append ;AUTO_SERVER=TRUE to the database URL. You can use the same database URL independent of whether the database is already open or not. This feature doesn't work with in-memory databases.
// Application 1:
DriverManager.getConnection("jdbc:h2:/data/test;AUTO_SERVER=TRUE");
// Application 2:
DriverManager.getConnection("jdbc:h2:/data/test;AUTO_SERVER=TRUE");
From H2 documentation:
It is also possible to open the database without file locking; in this
case it is up to the application to protect the database files.
Failing to do so will result in a corrupted database.
I think that if your application use always the same configuration (shared file database on network folder), you need to create an application layer that manages concurrency
I have Oracle RAC 10g environment with two nodes.
On connection we set the session TIME_ZONE using ALTER SESSION.
But, on switching the session to another node , RAC lost TIME_SONE settings.
How to keep session parameters upon switching to another RAC node?
Tx
If you're talking about Transparent Application Failover there is probably no easy way to do this:
You must also reexecute any session customizations, in other words,
ALTER SESSION statements, after failover has occurred.
There may be workarounds, depending on how you set the session settings. For example, if all the relevant sessions come from the same application, computer, etc., you can use a logon trigger that sets the same settings. You can find the relevent session using v$session.failed_over = 'YES', and matching other relevant columns in v$session.
Are the settings of oracle server like , the nls_date_format,.... attributes (I don't know really how many of these kind settings are there) , will be downloaded to the oracle client running on different machine by connecting to the SQL*plus using server host name?
Or the client will maitain its different set , assuming the client is SQL*Plus.
If the client is having its own settings ,is there any way If I can set the same settings as server. like export all settings from server and import those settings to client.
If the client is SQL Developer , is there any way to maintain the sync. between server settings and client's.
You can query the settings (about 20 variables) from the NLS-Views (NLS_DATABASE_PARAMETERS, NLS_INSTANCE_PARAMETERS, NLS_SESSION_PARAMETERS). By show parameter nls you can view the actual settings in SQL*Plus.
These can be altered by sysdba in several ways:
The database parameters are read from (s)pfile while startup. They can be altered via ALTER SYSTEM SCOPE=SPFILE if you use spfile. If you use pfile you have to edit it manually
The instance parameters are set by ALTER SYSTEM SCOPE=MEMORY and will be lost upon shutdown
Both at once can be altered using SCOPE=BOTH. This will be applied immediately and survive the shutdown
The client can override this for his own session in (at least?) two ways:
Set it for your session by ALTER SESSION in SQL*Plus
Set environment variables before client startup via export NLS_...=... in the shell
The latter overrides the earlier ones, so SESSION beats INSTANCE which eats DATABASE.
For your question: you can use a SELECT * FROM NLS_INSTANCE_SETTINGS and apply these to your current session by ALTER SESSION SET ... for each of these variables (maybe via some PL/SQL procedure). Another way would be just to unset all session parameters so that the instance parameters will be used.
If you do not set any NLS variables (especially NLS_LANG) in your environment, your session should be the same as the instance or the database ones. In practice this will never work as expected as you always have some locale settings that produce weired results in SQLP*Plus. ;-)
Just out of curiosity, a few days ago we had a discussion about whether there is a way to connect to the DB without using TNS Listener, the connection must be made by any program SQLPlus. Net, ODBC, and so on.
Basically only local connections can avoid the listener (ie you have to be already logged on to the machine that the database instance is running on).
Rather than relying on a listener to fork out a process to act on behalf of the connection, this is done by the local process. Generally it means that the local user needs to be run as 'oracle' as well. Sort of equivalent to a console logic.
It appears there isn't one magic bullet, but there are several ways.
For ODBC, have a look at this SO question.
There's a lot of good info at Connectionstrings.com/oracle as well.
You connect to Oracle via a client, such as sqplplus, or a java program (or tool) utilizing a protocol such as SQL*NET or JDBC (as examples) through the listener. The listener in turn forks a process on the target database (or assigns the connection to an existing process if you use shared servers).