Spring DatasourceTransactionManager not release connection after commit/rollback - spring

I have an Enterprise Application (ear) deployed in this configuration enviroment:
Weblogic 12c (12.1.1) + Oracle RAC 11g (release 2).
Web Module is an MVC application, implemented with Struts 2 and Spring-framework (3.2.2) for core services. Spring JDBC is used for database access with simple JdbcTemplate for single statements and DatasourceTransactionManager for complex ones. I noticed a strange behavior when I enable Weblogic jdbc logs. When I start a new transaction, I can see jdbc info logs about transaction creation, retriving jdbc connection from weblogic datasource pool and setting autocommit property to false value over connection itself. But I can't see transaction releasing connection log, and restoring autocommit flag to true value after commit/rollback invocation.
It's possible that Spring Transaction Manager does not release jdbc connection and does not restore "autocommit" value flag (to true)? After a while I can see within my application some persistent locks on db tables, causing an overall defect of my application and that I would not have depended on the behavior of the transaction manager.
Has anyone noticed a similar behavior?
Is it possible that jdbc connection is not released by the framework and it can compete in multiple transactions (as seen in jdbc log)?
Thanks
Paolo

Since you are using managed DataSource from WebLogic (JNDI?) you have to use managed TransactionManager as well:
<tx:jta-transaction-manager/>
should be enough:
if (weblogicPresent) {
return WEBLOGIC_JTA_TRANSACTION_MANAGER_CLASS_NAME;
}
And it is instead of that DatasourceTransactionManager.

Related

Apache Ignite JDBC driver - JDBC Connection Pool options

I'm currently trying to set-up Apache Ignite with C3P0 as my JDBC Connection pool, but I noticed that since the Ignite driver doesn't support transactions, C3P0's not usable.
Has anyone had any luck getting a JDBC connection pool going with the Ignite driver? Suggestions?
EDIT:
Updating with exactly why C3P0 doesn't work with Ignite's JDBC Driver
So take a look at this line of code
To create a new pooled connection, C3P0 attempts to set transaction isolation through the connection/driver.
That eventually leads us to this line of code in the Ignite driver, which basically tells us that the Ignite driver doesn't support SQL transactions.
Ignite itself DOES support transactions as specified here but it appears the JDBC implementation does not.
So I need an alternative to C3P0 if I want to set up a JDBC connection pool; any suggestions?
It turns out the JDBC driver for Apache Ignite isn't currently JDBC compliant. Specifically the part that breaks it is that it doesn't have transaction support. As a result, your typical JDBC-pool implementation won't work with the Ignite Driver
There's now a ticket for this here: https://issues.apache.org/jira/browse/IGNITE-4191
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("org.apache.ignite.IgniteJdbcDriver");
ds.setUrl("jdbc:ignite:cfg://cache=default#file:///the/path/to/ignite-config.xml");
ds.setInitialSize(2);
ds.setMinIdle(2);
Try BasicDataSource http://commons.apache.org/proper/commons-dbcp/configuration.html

MyBatis+Spring+Jersey with Oracle Seems to reuses SQL sessions

I'm creating a rest service using MyBatis 3.3.1, Spring 4.3, Jersey 2.22 and Oracle 12c. My transactions are being managed by Spring using the DataSourceTransactionManager and the #Transaction annotaion. I am also using a MyBatis pooled data source as my javax.sql.DataSource. What I don't understand if why database sessions are being reused.
In my application, I am setting an oracle client identifier: DBMS_SESSION.SET_IDENTIFIER("my id"). With the debug logging statements, I can see MyBatis creating new sessions for each of the MyBatis sql operations. I also have debug to print out the database session identifier from DBMS_SESSION.UNIQUE_SESSION_ID.
What I don't understand is that if I access my rest endpoint multiple times, the unique session id is the same and the identifier from my last access is still set.
Shouldn't a new oracle session be used every time MyBatis gets a new SQLSession? Why is the oracle session always the same?
Thanks.
Session in Oracle is bound to a connection.
You are using connection pooling so after one rest request is finished the connection is returned to the connection pool. Session is not terminated in this case.
You probably want to clear identifier on returning connection to pool and setting it on retrieving connection from the pool. The exact way to do that depends on the connection pool you are using. For built-in mybatis connection pool see this answer.

Spring JpaTransactionManager and Jackrabbit on the same database

We are using JPA in our project (using Oracle Database) and also want to use apache JackRabbit API. But If you use a database- persistence manager, the configured database connection must not be under the control of an external transaction manager. Jackrabbit implements distributed XA transaction support on a higher level, and expects to be in full control of the underlying database connection.
What is the solution for this problem?

How to get a new Connection from Hibernate SessionFactory after the DB restart without restarting the tomcat?

In my web application I am using hibernate & spring. The Hibernate SessionFactory object is being injected as a spring bean at the time of tomcat server start up. Normally it is working fine. But the problem arises when I shut down or even restart my database.
After restarting my database if I retrieve a session from Hibernate SessionFactory object and want to execute query i am getting org.hibernate.exception.JDBCConectionException: Could not execute query exception.
To overcome this problem I need to restart the tomcat server. After restart it creates the new SessionFactory object, so I don’t get the exception.
In a situation how can I get a new fresh connection with the database, so that I don’t need to restart the server again & again.
SessionFactory rebuild worked for me
Our app is using tomcat, hibernate(3.5.1) and Oracle db (there are actualy two instances - one is the main for the application and the second one - remote)
sometimes remote db restarts, after that exception occurs on each call
JDBCConnectionException:could not execute query
Caused by: SQLRecoverableException: No more data to read from socket
Fistly I added to configuration
hibernate.dbcp.validationQuery=select 1 from dual
hibernate.dbcp.testOnBorrow=true
hibernate.dbcp.testOnReturn=true
but without result.
Then I tried to close sessions and recreate it.
Finally what worked for me - after this exeption
sessionFactory recreate
sessionFactory.close();
sessionFactory = annotationConfiguration.buildSessionFactory();
This is not really Spring or Hibernate related. What you need to do is to setup your JDBC connection pool to test connections before returning them to whoever needs them (e.g. Hibernate). If the pool discovers that the connection in the pool is broken, it dicards it and tries another one from the pool. If all connections in the pool are broken, the pool will try to create new ones. Everything is transparent and your application won't even notice.
Which connection pool you use? In dbcp set validationQuery to"SELECT 1" nd consider setting: testOnBorrow=true, testOnReturn=true and testWhileIdle=true. For c3p0 check out the documentation.

Sharing JMS and Hibernate transactions in a Spring MDB using Oracle Streams AQ?

I'm using Oracle 11g for my database and its Oracle Streams AQ feature as JMS implementation.
For all I know, it should be possible to implement a Spring based message-driven POJO (MDP) that uses the same data source for both transactional data access and JMS transactions -- all without XA-Transactions (IIRC, this was marketed as a feature of SpringSource Advanced Pack for Oracle).
Is this possible using Hibernate as well? Ideally, my MDP would start a JMS transaction and read a message from a queue, then re-use the transaction for data access through Hibernate. If anything goes wrong, the JMS and database transaction would both be rolled back, without using 2-phase commit (2PC).
I'm not much of a transaction guru, so before I start digging deeper, can anyone confirm that this is possible and makes sense as well?
Update:
What I want is an implementation of the Shared Transaction Resource pattern. The sample code demonstrates it for ActiveMQ and JDBC, but I need to use Oracle Streams AQ and Hibernate.
Update2:
The SpringSource Advanced Pack for Oracle has been open sourced as part of Spring Data JDBC and it "provides the option of using a single local transaction manager for both
database and message access without resorting to expensive distributed 2-phase commit
transaction management".
2PC shouldn't be necessary, as you say, since the appserver should take care of it. However, you'll pretty much have to use JTA (i.e. JavaEE container) transactions, rather than vanilla DataSource transactions, since JMS only works with JTA.
This isn't a big deal, it's just a bit more fiddly:
Your Spring config should use
<jee:jndi-lookup/> to get a
reference to your container's
DataSource, and you inject that
data source into your spring-managed
hibernate SessionFactory.
You then need to introduce a transaction manager into the context (<tx:jta-transaction-manager/> should work in most app-servers).
In your Spring JMS MessageListenerContainer, plug the above transaction manager reference into it.
Does that all make sense, or should I elaborate? This setup should ensure that the container-managed transactions are held across JMS and Hibernate interactions.

Resources