My EJB has a method which will be running on a transaction started by a previous EJB (which is calling this one, having transaction attribute set to Required).
This method has multiple calls to a makeValid method that needs to commit separately from the main transaction:
I will have multiple threads acceding myMethod and I need them to see each other changes to the database occurring in the makeValid method, so I have declared makeValid method as static synchronized.
Also I want to avoid creating a new connection each time makeValid is called, so I have created a static reference for that 2nd DB connection.
My EJB uses the getConnection method from a helper class that goes like:
I am not sure about the connection management that the application server will be doing, so I would appreciate comments on the following items:
1- If I use a static variable to hold reference to this connection, the connection reference will be unique; after I invoke "getConnection", this unique reference will be tied to a physical connection that the application server will get from the connection pool, so that the physical connection used in the application will also be unique
2- the first time I run the application, as conn in the ConnectionHelper class is null, the getConnection method will return a new connection; but the next time I execute the application, as the static staticConnection still "lives", conn in the ConnectionHelper class will no longer be null, so that invoking getConnection will always be returning the same physical connection
3- If the physical connection is lost, I will have a valid reference tied to an invalid connection
4- As the connection is static, only when the application server is restarted I will be able to get a new valid connection
5- How could I guarantee that a valid physical connection is used each time the EJB is invoked?
6- When I create a 2nd connection object like this:
Connection specialPurposeConnection = (new ConnectionHelper()).getConnection();
the actual physical connection being used (got from the connection pool) may be the same that was returned for mainConnection, so when I will be invoking
I may unwantedly commit everything from both mainConnection and specialPurposeConnection.
I suppose some of these are wrong...
Thank you in advance for help on this topic.
The short answer is you are asking by trouble with this. A static connection will be useless shortly as it will eventually get closed or time out. An instance variable connection could have the same problem. This is why people use connection pools.
Regarding sentence 6, as the first connection still hasn't been committed or rolled back, it hasn't been returned to the connection pool, so if I invoke getConnection to get a 2nd connection this will actually be a different physical connection and it will commit separately from the other one (so sentence 6 is wrong). Is this correct?
as the first connection still hasn't been committed or rolled back, it hasn't been returned to the connection pool
Slight nuance: Committing or Rollback does not return the connection to the pool. Closing the connection returns it.
But your findings are correct. Your second connection runs in isolation from the one that is still in use, and will not commit or roll back changes made in the first one.