Is setting context in a JPA connection safe?

I need to set some context to each database operation (I tried to use the Oracle package-level variables, but due to some problems with recompiling the package I will experiment with DBMS_SESSION and / or DBMS_APPLICATION_INFO ), so we can get specific information about the user, anywhere where necessary (procedures, triggers, etc.), instead of having dozens of database connections identified as "JBoss".

I wrote interceptor Java EE, which intercepts calls to @Stateless bean. It causes Oracle function to set a session context (see this question for some code examples How to determine whether a transaction interceptor in Java EE 6 is active ).

My first concern was related to the connection pool. At first I thought that the default spread @PersistenceContext, provided by the Java EE, will be sufficient to ensure that all work on the same connection / transaction / the EntityManager, and I had to just cancel all the end of my interceptor (in the finally block) before the connection is returned to the pool. It seemed a bit fragile, but I thought it might work.

Then I learned that Hibernate has hibernate.connection.release_mode property ( Hibernate the docs about hibernate.connection.release_mode , Documents Red Hat on org.hibernate.ConnectionReleaseMode ) and that the default behavior and is recommended when using JTA transaction is to release connections after each operator (although the docs say something about the re-acquisition of the same basic compound, which just confused me).

Now I'm not even sure I can safely install something in the interceptor, which will only be visible to this user / operation, without running the risk that someone else will grab the same connection in the middle of my business method and create a mess with my custom context. I understand that the variables of the Oracle database session is stored for the connection, rather than a transaction or @PersistenceContext (personal data base is not aware of the context of the persistence in the end, and the connection can be used for multiple transactions).

I'm going to give up, because it looks increasingly fragile, as I learned more about the details of the implementation of all relevant technologies. Is it possible to make this concept a user context to work, or should I try a totally different approach? And how can I test / debug my implementation, to ensure that there are no problems with concurrency? I have not found any useful event listener to monitor the behavior of the structure and creating a program for stress testing the server works too hard to invest in something that I'm not sure that will still work.

I am using JBoss AS 7.1, EJB 3.1, Oracle 10g database and JPA 2.0 (supported by Hibernate, although we do not use any the Hibernate-specific API) data.

+4
source share
2 answers

So I'll answer your question with all the things that I have discovered in recent years.

To understand the behavior of the server, I changed the configuration of the JBoss, to use a pool of connections 1, so I was able to detect when someone else is blocked.

If the current transaction is within a transaction (e.g., @TransactionAttribute (REQUIRED)), the compound would not be used for anything else until the transaction is completed (the other clients have to wait). However, if you read the data without a transaction basis, other customers can get the same connection as long as you are not using it, even before the completion of your business method (I do not know whether this is the default behavior and how implementation is realized in detail).

Hibernate really releases the connection after each default application and so the connection can be reused in non-transactional method. On the other hand, JDBC, and JEE have functions necessary for the re-acquisition of the same compound, if you were still in the same transaction.

But why Hibernate frees the connection that he is going to retrain later? If Hibernate is not released it, some JEE servers might think that Hibernate flows through the connection when it opens a connection to the nested EJB call and leaves it open for the re-use of the caller. This is explained in this report:

http://www.mail-archive.com/ hibernate-dev@lists.jboss.org /msg00612.html

To be safe, all the data that we need to save (and later presented to the user), explicitly passed as parameters, but for logging purposes, we used some of the data stored in an Oracle session, knowing that the connection can not be re-used by other clients if you use a transactional business methods.

Refresh . It seems that you can do what I want, using some parameters of the application server associated with the connectors and / or custom data sources (not sure what the best answer here: https://developer.jboss.org/thread/250132 )

+2
source

I personally would not try to set the individual parameters in the JDBC-connection from the pool. In the end, the pool idea is that all the connections are identical. Therefore, unless your idea of ​​the interceptor would work, I am also worried about how it will be brittle. Any errors in this implementation would be the most disgusting kind of race conditions.

On the other hand, since you are using the Oracle, you can look for EclipseLink. It implements JPA2 and largely funded by Oracle, so it supports all of its unusual features. You might want to explore the 'Isolated client sessions . It supports virtual private database, which require individual tuning session. Thus, it would be a solution if you need to change a session context.

+2
source

All Articles