We have an existing j2se project that already uses JPA and guice-persist. Now, because we want to add JMS functionality, there is a request for 2-phase-commit and JTA. We'll use the bitronix transaction manager because there's no container (like spring).
To my understanding, the first thing we have to do is to change the transaction-type of the persistence unit from RESSOURCE-LOCAL to JTA, because we want database transactions to vote for commit rather then commit. The commit is done on phase 2 after collecting all votes.
With guice-persist we use the #Transactional annotation for methods that should run in a single transaction. The JPAPersistModule provides an EnitiyManagerFactory and it is used for guice-persist internal classes, like JpaLocalTxnInterceptor that wraps the annotated methods.
Now I get exceptions like
java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()
at org.hibernate.ejb.AbstractEntityManagerImpl.getTransaction(AbstractEntityManagerImpl.java:1009)
at com.google.inject.persist.jpa.JpaLocalTxnInterceptor.invoke(JpaLocalTxnInterceptor.java:57)
...
because the JpaLocalTxnInterceptor calls getTransaction() on the provided entity manager.
I'm quite stuck, at the moment. Is there any way to use guice-persist together with JTA or o we really have to drop guice-persist from the project? Or, is there any replacement for guice-persist if we want to do JTA (with Bitronix)?
Had a similar situation. In our case we were using Guice + Jooq. We wanted Jooq because we have a large legacy Rails DB and wanted fine control plus speed. We picked Guice over Spring because we felt it is a better framework, and it is much faster and we like compile time checking.
We could NOT use Guice persist with Jooq, so we :
Use Atomikos JTA (free version)
Wrote our own #Transactional AOP annotation interceptor;
Our injectable Service provides the java.sql.Connection to our jooq processors, but always supply an Atomikos DataSource bean
We basically modified this code:
http://www.dailyjavatips.com/2011/10/24/database-transactions-google-guice-aop/
So that example uses regular JDBC Tx, but we modified it so it would use Atmomikos' JTA aware Tx instead.
Works like a charm!
Oje
Related
I am trying to understand the transactions, and more specifically i am doing it using Spring framework. Going through the material that i have (both internet and books), i see these terminologies:
Container managed transactions (CMT).
Bean Managed transactions (BMT).
Java transaction API (JTA).
Also, for a large enterprise level application, terminologies like "local" and "global" transactions too i have encountered.
What i have understood, is that global transactions is for the cases in which we are managing two or more different resouces (like One Oracle DB, other MySQL etc) and commits/rollback to them happen if both are success/failure. Local transactions is for when we have only one resource to manage (like only one DB connection to MySQL).
I have following doubts:
While writing a simple JDBC standalone program, we can code to commit/rollback. I believe this is example of local transaction, is this correct? And is this transaction taken care by "JDBC" library itself or the drivers?
What is CMT? What i understand is that Container takes care of the transaction management (like Jboss AS). If this is correct, how internally does it manages? Are CMT local or global? Do they use JDBC API's internally to manage the transactions?
What is BMT? This i am not able to understand. We can have application deployed in an App server (and i believe in those cases the transaction would be managed by Container) or i can write an standalone application in which i can use the transaction management code myself (try .. catch block etc). So, which category BMT falls?
While reading Spring framework, i read that Spring framework have its own way of managing the transaction. Down the line, i read Spring Framework uses JTA to manage transactions? I am confused about this. If JTA is API, do we have multiple vendors who implement JTA (like for JPA, we can have multiple vendors who provide the implementation e.g. Hibernate).
Is JTA for local or global transactions? When i write a simple JDBC program to manage transaction, does it use API's which comply JTA? Or is JTA totally different from transaction management which simple JDBC program uses?
Same for CMT, does CMT follow the rules which JTA has in place (the API's primarily)?
It would be great if you answer point-wise, i did search on net, my doubts are still not answered.
Concerning local/global transaction: by global I suppose you are talking about XA transaction (2 phase commits : http://en.wikipedia.org/wiki/X/Open_XA). This is just mandatory when you deal with multiple databases or transactionnal resources.
yes it's a "local transaction", it means only one database is
part of the transaction. The transaction is managed by the database
and controlled by JDBC in that case.
CMT : Container Managed: the container will detect the start and
the end of the transaction and will perform commit/rollback
depending on method return status (successfull return : commit,
exception : rollback). CMT rely on JTA to manage transactions on its
resources. Then it's up to the proper resource adapters (RA) to talk
to jdbc or any other drivers related to your EIS (data). Look at
http://docs.oracle.com/javaee/5/tutorial/doc/bncjx.html
BMT: it means it's up to the bean to control transaction
boundaries. It's pretty rare to use this kind of transaction
management these days. With BMT you control the UserTransaction
object, it's an error to control transaction boundaries directly
with JDBC. Bear in mind also that even if you are in BMT some
framework like JPA (not JTA) will invalidate current transaction on
any error even if you did not explicitely requested a rollback. It
means it's quite hard/dangerous/useless to use BMT.
JTA (I hope you did not mispelled JPA) is at another level: JTA
the API a resource adapter must implement to be part of a container
transaction. Apart from UserTransaction class (what you'll use in
BMT to control transaction boundaries) you have nothing to do with
JTA. There is no multiple implementation of JTA but there is multiple implementation of JTS (Java Transaction Service), each application server vendor implements their own JTS.
JTA is a API for framework designer, JTA impose a contract to the
Resource Adapter RA, and the RA will use JDBC or any other API to
deal with it's EIS (Enterprise Information Storage, let's call it
your DB). JTA works for XA and non XA transactions (if your RA supports XA transactions).
CMT uses JTA, but again JTA is a lowlevel contract between
components of the application server. Application designer should
not care about JTA.
I am currently having a problem with understanding a concept of JPA.
I am currently using/developing recent EclipseLink, Glassfish, Derby database to demonstrate a project.
Before I develop something in much bigger picture, I need to be absolutely sure of how this PersistingUnit work in terms of different scopes.
I have bunch of servlets 3.0 and currently saving user's associated entity classes in the request.session object (everything in the same war file). I am currently using Application-managed EntityManager using EntityManagerFactory and UserTransaction injection. It works smooth when it is tested by myself. The different versions of entities occur when 2 people accessing the same entities at the same time. I want to work with managed beans cross the same WAR, same persistence unit if possible.
I have read http://docs.oracle.com/javaee/6/tutorial/doc/bnbqw.html and bunch of explanations of those scopes which don't make sense at all for me.
Long story short, what are the usage and difference of app and container managed EntityManagers?
When you say application managed transaction it means its your code which is supposed to handle the transaction. In a nutshell it means:
You call:
entityManager.getTransaction().begin(); //to start a transaction
then if success you will ensure to call
entityManager.getTranasaction().commit(); //to commit changes to database
or in case of failure you will make sure to call:
entityManager.getTransaction().rollBack();
Now imagine you have a container, which knows when to call begin(), commit() or rollback(), thats container managed transaction. Someone taking care of transaction on your behalf.
You just need to specify that.
Container managed transaction(CMT) could be regarded as a kind of declarative transaction, in which case, transaction management is delegated to container (normally EJB container), and much development work could be simplified.
If we are in a Java EE environment with an EJB container, we could use CMT directly.
If we are in a Java SE environment, or a Java EE environment without an EJB container, we could still take advantage of CMT, one way is to use Spring, which uses AOP to implement declarative transaction management; Another way is to use Guice, which uses a PersistFilter to implement declarative transaction.
In CMT, a container (whatever an EJB container, Spring or Guice) will take care of the transaction propagation and commit/rollback stuff;
Application managed transaction (AMT) differs from CMT in that we need to handle transactions programmatically in our code.
I have an application that has a struts 1.1 and EJB 2 combination, but now we are introducing a new piece into it with hibernate 3.2. The hibernate DAO's run in parallel with the EJB 2 session bean DAO's with pure JDBC. I am concerned about the jdbc connections management in this case. Since EJB 2.0 has container managed connections and transactions. But in the case of hibernate we begin and commit a hibernate transaction, Will it be safe to assume there will not be any issues with this architecture.
Need some analysis help.
PM
I was contemplating on the same issue, if hibernate module which might access existing tables being used by JDBC DAO's whose transaction is managed by Session Beans. But here is my approach:
I will have a delegate that invokes the EJB session bean, and since this bean will be responsible to manage transactions, I will create my hibernate DAO's and invoke them from this session bean, which I assume will not have any issues.
The hibernate session factory for this application will be instantiated once using the hibernate plugin that will be part of the struts config xml and will be saved as part of the servlet context and then the action class will pass this sessionfactory instance from the EJB session bean delegate to the hibernate DAO.
I guess this will be a clean approach, since the transaction will be managed by the EJB Session bean which are deployed onto the websphere. The JDBC connection pools management since is configured on the websphere and being accessed using the datasources, hibernate does not have to worry about this.
Please help me if I am on the right path with my assumptions ?
Transactions demarcate logical unit of work and hence are inherently isolated. But I am wondering why you need a combination of both. If you are already using EJB2 + JDBC why not stick to this?
Hibernate can be used without any problem with CMT (or BMT) session beans, share a connection pool with JDBC code and participate in the same transaction.
See the whole section 11.2. Database transaction demarcation and in particular 11.2.2. Using JTA.
What is not clear is if the Hibernate module will be "isolated" from the entities managed via JDBC. If you'll access the same tables via both APIs, you'll have to take some precautions:
don't expect to mix JDBC entities in a graph of Hibernate entities (the inverse is possible though).
respect and mimic Hibernate optimistic concurrency strategy when updating rows via JDBC
bypassing Hibernate's API won't trigger any cache update (if you're using the 2nd level cache) in which case you'd have to trigger it yourself.
Here is one of the possible solutions
A common JNDI Datasource, which will be used both in EJB's and Hibernate.
Quote from hib official docs:
Starting with version 3.0.1, Hibernate added the SessionFactory.getCurrentSession() method. Initially, this assumed usage of JTA transactions, where the JTA transaction defined both the scope and context of a current session. Given the maturity of the numerous stand-alone JTA TransactionManager implementations, most, if not all, applications should be using JTA transaction management, whether or not they are deployed into a J2EE container. Based on that, the JTA-based contextual sessions are all you need to use.
end of quotation
I use tomcat6 as a servlet container, and need to integrate Hibernate 3.2 into the project.
I found a document how to configure SessionFactory lookup through JNDI, though it does not work as expected.
Quote:
Hibernate works in any environment that uses JTA, in fact, we recommend to use JTA whenever possible as it is the standard Java transaction interface.
End of quote.
In hibernate config I indicate current_session_context_class = jta
and now I get an error "No TransactionManagerLookup specified".
The problem is that Tomcat does not support JTA, and to get it worked,
if I understand it correctly,
you need to add JOTM or other library to Tomcat.
But according to quote it is recommended to use JTA.
What can you recommend in this situation?
Your choices are pretty clear:
Either change to a servlet container that does support JTA
Find another transaction mechanism other than JTA, such as programatically controlling transactions yourself.
What can you recommend in this situation?
Do without JTA and use the Open Session In View pattern to handle the session.
I am planning an application that must provide services that are very much like those of a Java EE container to third party extension code. Basically, what this app does is find a set of work items (currently, the plan is to use Hibernate) and dispatch them to work item consumers.
The work item consumers load the item details, invoke third party extension code, and then if the third party code did not fail, update some state on the work item and commit all work done.
I am explicitly not writing this as a Java EE application. Essentially, my application must provide many of the services of a container, however; it must provide transaction management, connection pooling and management, and a certain amount of deployment support. How do I either A) provide these directly, or B) choose a third party library to provide them. Due to a requirement of the larger project, the extension writers will be using Hibernate, if that makes any difference.
It's worth noting that, of all of the features I've mentioned, the one I know least about is transaction management. How can I provide this service to extension code running in my container?
Hi I recommend using the Spring Framework. It provides a nice way to bring together a lot of the various services you are talking about.
For instance to address your specific needs:
Transaction Management/Connection pooling
I built a spring-based stand-alone application that used Apache commons connection pooling. Also I believe spring has some kind of transaction mgmt built in.
Deployment support
I use ant to deploy and run things as a front-loader. It works pretty well. I just fork a seperate process using ant to run my Spring stand-alone app.
Threading.
Spring has support for Quartz which deals well with threads and thread pools
DAO
Spring integrates nicely with Hibernate and other similar projects
Configuration
Using its xml property definitions -- Spring is pretty good for multiple-environment configuration.
Spring does have transaction management. You can define a DataSource in your application context using Apache DBCP (using a org.apache.commons.dbcp.BasicDataSourceorg.springframework.jdbc.datasource.DataSourceTransactionManager for the DataSource. After that, any object in your application can define its own transactions programatically if you pass it the TransactionManager, or you can use AOP interceptors on the object's definition in your application context, to define which methods need to be run inside a transaction.
Or, the easier approach nowadays with Spring is to use the #Transactional annotation in any method that needs to be run inside a transaction, and to add something like this to your application context (assuming your transactionManager is named txManager):
<tx:annotation-driven transaction-manager="txManager"/>
This way your application will easily accept new components later on, which can have transaction management simply by using the #Transactional annotation or by directly creating transactions through a PlatformTransactionManager that they will receive through a setter (so you can pass it when you define the object in your app context).
You could try Atomikos TransactionsEssentials for Java transaction management and connection pooling (JDBC+JMS) in a J2SE environment. No need for any appservers, and it is much more fun to work with ;-)
HTH
Guy