I wan to know how the transaction is internally implemented in EJB. I want to know the logic they use to create a transaction. if you could point out some articles that would be helpful
Hibernate doesn't implement transactions, it relies on and wraps JDBC transactions or JTA transactions (either container managed or application managed).
Regarding EJBs, if you want to understand the details of a JTA Transaction Manager, you'll need to be fluent with the JTA interfaces UserTransaction, TransactionManager, and XAResource which are described in the JTA specification. The JDBC API Tutorial and Reference, Third Edition will also be useful to understand the XA part of a JDBC driver.
Then, get the sources of an EJB container (like JBoss) or of a standalone JTA Transaction Manager (like Atomikos) to analyze the TM part. And good luck.
This question could have answers at many levels.
A general discussion of what's going on can be found here
My summary goes like this ... First, somewhere there must be a transaction coordinator, the EJB container will know about the coordinator - typically that's part of the application server. So all the EJB container has to do is to call
someobject.BeginTransaction()
that's it. The actual API the EJB container uses is JTA. EJBs can actually use Bean Managed transaction transaction or Container managed transactions. In the Bean Managed case the implementer nhas to make the JTA calls. More usually we use Container Managed transactions (CMT). In which case the container has logic which is run before the implementation is reached. For example:
if ( we're not already in a transaction )
begin transaction
call the EJB implementation
and later the container has logic
if ( finished processing request )
commit transaction
with other paths to abort the transaction if errors have happened.
Now that logic is more complex because CMT EJBs are annotated with transaction control statements. For example you can say things "if we already have a transaction, use it" So if one EJB calls another only a single transaction is used. Read up the EJB spec for that.
However all that's pretty obvious in any write-up of Java EE EJBs. So I suspect that you're asking moe about what happens inside the JTA calls, how the transaction manager is implemented and its relationship to the transactional resource managers (eg. Databases). That's a huge topic. You've actually go implementations of the XA distributed transaction protocol down there. Frankly I doubt that you really need to need to know this. At some point you have trust the APIs you're using. However there is one key detail: your Transaction Manager (typically the App Server itself) must be able to tell the REsource Managers the fate of any given transaction, and that information must survive restart of the App Server, hence some persistent store of transaction information must be kept. You will find transaction logs somewhere, and in setting up the App Server you need to make sure those logs are well looked after.
From EJB in Action book
The protocol commonly used to achieve multiple resource is the two-phase commit. The two-phase commit protocol performs an additional preparatory step before the final commit. Each resource manager involved is asked if the current transaction can be successfully committed. If any of the resource managers indicate that the transaction cannot be committed if attempted, the entire transaction is abandoned (rolled back). Otherwise, the transaction is allowed to proceed and all resource managers are asked to commit.
A resource manager can be a database, for instance. Others examples includes a Message Service. The component which coordinates transactions is called Transaction manager.
Suppose you have an application which involves two distincts databases. How does Transaction manager performs its work by using Two phase commit protocol ?
Transaction Manager ask database 1 if it can commit the current transaction
If so, ask database 2 if it can commit the current transaction
Transaction Manager ask database 1 to commit
Transaction Manager ask database 2 to commit
Hibernate is built on top of the JDBC API. It just coordinates one database. So if you call
session.commit();
Behind the scenes, it call
connection.commit();
If you really want to study Transaction internals, my advice is Java Transaction Processing book.
Hibernate has TransactionFactory:
An abstract factory for Transaction instances. Concrete implementations are specified by hibernate.transaction.factory_class.
It has implementations: JDBCTransactionFactory, JTATransactionFactory, CMTTransactionFactory. These factories create an instance of Transaction - for example JDBCTransaction.
Then I can't tell you what happens for JTA and CMT, but for JDBC it's as simple as setting the auto-commit to false (when you call begin a transaction):
connection.setAutoCommit(false);
And respectively on transaction.commit(): connection.commit()
If any exception occurs when operating with the session, it invokes connection.rollback()
Another good read would be the JTS articles by Brian Goetz; links:
http://www.ibm.com/developerworks/java/library/j-jtp0305.html
http://www.ibm.com/developerworks/java/library/j-jtp0410/index.html
http://www.ibm.com/developerworks/java/library/j-jtp0514.html
Related
In my standalone java application, jms and hibernate are used for fulfilling my requirements. I used the JTA transaction manager for the transaction management purposes. Can i enlist the XAResource for the hibernate and jms in the jta transaction to ensure the atomicity of my application.
Yes, it's possible. Called sometimes two-phase commit, it synchronises transactions between multiple resources.
First of all make sure you're RDBMS supports and has the feature turned on. In PostgreSQL, for example, this means setting the max_prepared_transactions configuration parameter from postgresql.conf to something above 0.
Also, make sure the JMS queue you're using support this transaction method. In Wildfly this means adding transaction="xa" on pooled-connection-factory.
Is it good practice to have interceptors to manage transactions?
I have a strong point though that it is equivalent to begin and commit in the action itself.
Why should I use interceptor managed transactions at all?
It's not bad practice, for example Spring framework uses aspects for 'auto-begin' and 'auto-commit' transactions using #Transactional annotation.
Why should I use interceptor managed transactions at all?
It reduces a lot of boilerplate code: opening connection, beginning transaction, committing transaction and closing connection.
But if you want to write your own transaction manager using interceptors - beware of concurrency issues
According to image you posted:
It's better not to expose transaction management from Service layer. It's better if your presentation layer don't know anything about Transaction management. So try to encapsulate your transaction management code in service layer or in DAO layer. If your presentation layer manages transaction and service layer is not, it's mean your services is not self-contained, and they can be reused by other client only if client provide some transaction management logic.
From Comments:
Better is to put transaction management code to service layer, because
service layer usually performs some business level operations, which
must be performed within one transaction. So your service method can
use 2 or more DAOs to perform all DB operations in one transaction.
Sorry, there is no links - I tell it your from my experience.
I am working on a stand-alone application that uses both JMS and Hibernate.
The documentation suggests JTA has to be used if I want to have transactions across both resources.
However, right now with a #Transaction annotated DAO method (and HibernateTransactionManager), this already seems to work. When I call send() on the JmsTemplate, the message is not immediately sent, but rather the JMS session is committed with the Hibernate session as the method returns.
I didn't know how this is possible without the JtaTransactionManager, so I checked the source code. It turns out both the wrapper for Hibernate and JmsTemplate registers the sessions with TransactionSynchronizationManager and the JMS session will be committed when the Hibernate session commits.
What's the different between this and a JTA transaction. Can I use this to replace the latter??
In short no, you can't get support for 2-phase commit without a JTATransactionManager and XA aware datasources.
What you are witnessing is a co-ordination of two Local Transactions supporting 1-phase commit only. Roughly performing this sequence of events...
Start JMS Transaction
Read JMS message
Start JDBC Transaction
Write to database
Commit JDBC Transaction
Commit/Acknowledge JMS
The JMS transaction will be started first wrapping the nested JDBC transaction, so that the JMS queue will rollback if the Hibernate/JDBC commit fails. Your JMS Listener Container should be setup not to acknowledge="auto" and instead wait for the Hibernate transaction to complete before sending the acknowledgement.
If you only have these two resources then the issue you will have to consider is when Hibernate succeeds in persiting then you get an Exception before you can acknowledge the JMS server. Not a big issue as the JMS message is not lost and you will read it again.
However
You must write your MessageListener to handle duplicate messages from the server
You must also handle a message that cannot be processed due to bad data and ending up in an infinite loop of trying to comsume it. In this case the server may be configured to move the message to a "dead message queue", or you deal with this yourself in the MessageListener
Other options and further reading
If your JMS server does not support XA (global) transactions this is pretty much your only solution.
If JMS server does support XA transactions but JDBC doesn't then you can use a JTATransactionManager and use the LastResourceCommitOptimisation. There are open source JTATransactionManagers you can use like JOTM
This JavaWorld article goes into more detail on your problem space.
Although this has been answered in detail by Brad, i would like to address a very specific part of your query:-
I didn't know how this is possible without the JtaTransactionManager
From the spring documentation:-
When a JTA environment is detected, Spring’s JtaTransactionManager will be used to manage transactions
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-jta.html
I am loading a large set of data into a database from a webservice. I am using eclipslink for persistence and running the application on glassfish 3.0. I run into problems on my test data set in that there are a few foreign key constraint violations. I am fine with the violation, I do not want that data if it is not complete. My problem however comes in that the exception is thrown in the container. That then marks my transaction for a rollback, and I get no data at all then.
I would like to continue using JTA but am not sure if I can do what I want to achieve, and that is create my own JTA transaction so I can control when it commits,etc. I am not sure if that is a good idea though as I feel by doing so I may be destroying some of the benefits of using JTA.
So is it possible to get a JTA transaction?
Do the database work in a method of a session bean. Annotate that method with:
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
It will be given its own transaction. The outer transaction will be suspended while it does its stuff.
http://wiki.eclipse.org/Using_Advanced_Unit_of_Work_API_%28ELUG%29#Integrating_the_Unit_of_Work_with_an_External_Transaction_Servicestrong text**
Read How to Acquire a Unit of Work with an External Transaction Service. Apparently you can snatch the UserTransaction and/or start your own by querying the container JNDI for UserTransaction
We've got a Spring based web application that makes use of Hibernate to load/store its entities to the underlying database.
Since it's a backend application we not only want to allow our UI but also 3rd party tools to manually initiate DB transactions. That's why the callers need to
Call a StartTransaction method and in return get an ID that they can refer to
Do all DB relevant calls (e. g. creating, modifying, deleting) by referring to this ID to make clear which operations belong to the started transaction
Call the CommitTransaction method to signal to our backend that the transaction can be committed now (or in the negative case RollbackTransaction will be called)
So keeping in mind, that all database handling will be done internally by the Java persistence annotations, how can we open the transaction management to our UI that behaves like a 3rd party application that has no direct access to the backend entities but deals with data transfer objects only?
From the Spring Reference: Programmatic transaction management
I think this can be done but would be a royal pain to implement/verify. You would basically require a transaction manager which is not bounded by "per-thread-transaction" definition but spans across multiple invocations for the same client.
JTA + Stateful session beans might be something you would want to have a look at.
Why don't you build services around your 'back end application' for example a SOAP interface or a REST interface.
With this strategy you can manage your transaction in the backend