Spring Transaction Management and Oracle Stored procedures - spring

I am currently integrating transaction management into my code.
I am trying to set it up against stored procedures that already exist.
The stored procedures have a commit at the end of them.
In my eclipse console, I can see the transaction management code being invoked
datasource.DataSourceTransactionManager Initiating transaction rollback
datasource.DataSourceTransactionManager Rolling back JDBC transaction on Connection [oracle.jdbc.driver.LogicalConnection#1544055]
datasource.DataSourceTransactionManager Releasing JDBC Connection [oracle.jdbc.driver.LogicalConnection#1544055] after transaction
But I can still see remains of the record that should have been rolled back in my database tables.
If we use spring transaction management, should we remove all commits from our stored procedures?
Thanks
Damien

Related

How Spring transaction is mapped to underlying database connection

I am trying to understand in background how transaction is mapped to jdbc connection i.e one jdbc connection can be parallely used for multiple spring transactions at the same time or one connection is totally reserved for one transaction at a given time and only released after transaction is complete.
I my opionion one of the best way to understanding how Spring managed transactions is reading Transaction Management Reference Doc.

Javers is grabbing all of my available Connections

One other thing I'm finding, is that it appears that Javers is grabbing all of the available Connections out of my connection pool (created via Spring DataSourceBuilder). I'm not using Hibernate/JPA, just straight JDBC via JdbcTemplate and mostly MyBatis for my entity queries.
I've added a logging statement to my ConnectionProvider for Javers, and at the start of the application when it queries for the schema, it pulls 4 connections to check for each of the tables, and then never returns any of them even after the commit from the PlatformTransactionManager.
I understand from https://stackoverflow.com/a/35147884/570291 that it's supposed to participate in the same connection as the current Transaction. Since I'm not using Hibernate/JPA, does that mean I need to implement the connection tracking/etc from MyBatis to the Javers ConnectionProvider to return the same connection (if there is one), and then handle closing (returning to the pool) of that connection at the end of the transaction?
I found DataSourceUtils.getConnection(DataSource) which is a Spring utility class to get a connection from the given DataSource including if it's tied to a current transaction or not as appropriate. Using that in the ConnectionProvider looks like it's done the trick of keeping the connection for the existing transaction.
JaVers won't return connections to application's connection pool for the same reason as it won't call sql commit or rollback.
Managing connactions and transactions is the application's responsibility, not JaVers. We call it passive mode, from Javers doc:
- JaVers doesn’t create JDBC connections on its own and uses connections provided by an application (via ConnectionProvider.getConnection()).
- JaVers philosophy is to use application’s transactions and never to call SQL commit or rollback commands on its own.
Thanks to this approach, data managed by an application (domain objects) and data managed by JaVers (object snapshots) can be saved to SQL database in one transaction.
In JaVers project there is no mybatis support, so you need to implement ConnectionProvider for mybatis on your own.
Proper implementation of ConnectionProvider shouldn't create new sql connection for every getConnection() call. It should return the connection which underlies current application's transaction. Typically, it's implemented using ThreadLocal.
As you mentioned, ConnectionProvider should handle committing transactions and closing connections.

Weblogic XA transaction, delayed writing to db even after commit

My application uses XA transaction for writing to db and publishing message out on MQ.
However Consumer application intermittently not able to find data in the database.
We are using
Weblogic 10.3 and oracle 10g
I thought as part of XA transaction, message will be sent out only when db commit is complete.
Any inputs on this will be appreciated..
Thanks.
The question is what data source are you using to execute xa transactions. If it is the emulated one this is expected, as you are only simulating xa.

Spring transaction management records are not inserted into db table after transaction is commited

I am using Spring transaction management using Hibernate Transaction Manager. I have declarative transactions configured on a class. Transaction starts and commits. But while commiting its not inserting any records to table. Not able to see any Insert table log message. Is transaction uses some other hibernate session object. How to make it to use session object currently in use.

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