I want to find a way to apply a custom interceptor with JTA #Transactional annotation.
I have a method with #Transactional which is one of business-transactions. In that method I want to:
do some database operation
publish some topic with a cloud messaging service.
If any of the two fails both of them should not be done (i.e. they should be rolled back).
Currently I use Google Cloud pubsub as the messaging service, but this library does not seem to be compatible with JMS or JTA. Therefore, I'm wondering if I can implement a custom interceptor for that library (e.g. queue messages during a transaction, and publish the queued messages when the transaction is successfully committed).
Is there any good idea to do that?
Framework is Quarkus, and the JTA implementation is Narayana for now.
No. JTA #Transactional requires your messaging platform to have a transaction manager that ideally support the XA API or at least some form of transactional semantics: begin(), commit() and rollback() - begin() might not be necessary, but definitely rollback() is.
If something goes wrong with the second message inside your transaction, you want to make sure that the first message 'disappears' as if it never happened and rollback the complete transaction.
But, as of now, Google pub/sub has no notion of transaction, transaction IDs or commit() and rollback().
We recently had a very unexpected issue in PROD which we manage to reproduce but we still don't have a clear explanation of what is causing it and more importantly how to fix it.
Our system is a vendor workflow framework that offers us hooks to add our custom behavior. It is running on WebSphere Application Server and it is a mix of Camel and Spring and EJB. Initially it was pure EJB but a few years ago the vendor added Camel with a view of getting rid of application server.
Now the problem:
The start of processing is a Camel route which is transacted with PROPAGATION_REQUIRED attribute. Part of the processing there is a local call to an EJB method. There is not explicit setting for any of EJB methods exposed apart from being Container managed. This means the EJB call should get the implicit value of REQUIRED. Part of the EJB call there is data change happening. The reference to the EJB is obtained using some code like below:
String repositoryName = MBLLookupUtil.getInstance().getRepositoryName();
RepositoryInstanceFacadeHome facadeHome = MBLLookupUtil.getInstance().getRepositoryInstanceFacadeHome(
repositoryName);
RepositoryInstanceFacade facade = facadeHome.create();
// Here is when the data change happens:
facade.doSomeWork();
The application logs show clearly that the EJB processing is happening in the same thread as the client. After making the call there is more work in the calling client when a Timeout exception happens.
We expect that both data change on client side and that changed as part of the EJB call will be roll backed, however the data changed by EJB call stays committed while the client side (Camel) gets roll backed.
In the spring application context we use WebSphereUowTransactionManager which is the IBM recommended way of configuring transaction manager:
<bean id="txManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/>
Any hints about what could cause this or how we could further investigate would be great appreciated. Thank you in advance.
UPDATE:
As advised in tomgeraghty3's comment I made a code change to log the value of TransactionSynchronizationManager.isActualTransactionActive() and the result was true
UPDATE 2:
We found out where the issue was by spending hours of analyzing decompiled vendor code. The transaction propagation was configured in an application-context.xml file but it was also overwritten straight in the POJO code with an #Transactional(propagation=REQUIRED_NEW) annotation. We proved that was the problem by removing the POJO class from the vendor jar and adding one with no annotation with the same package in one of ours. Very dirty just to prove our suspicion.
Now our bigger challenge would be to persuade the vendor address the issue. Hope it is just a bug and not an impacting change.
I'm working on a REST webservice that uses hibernate as an OR Mapper. I recently upgraded hibernate from 3.2 to 4.3 and got an error I described here. Basically my transaction got rolled back somewhere and then I got an error when I wanted to use that session again (which is correct hibernate behavior).
I think I figured out why I got that error. It is because when I receive the request a long session is started. This session also opens a transaction that will be open for a longer period of time. Besides this long running session/transaction also some small session/transaction should be opened on the same thread. As far as I found out, all sessions get the same UserTransaction to work with and since the small transactions commit and rollback this transaction I run in the error described in my other post.
Since I'm working with a huge code base it is that easy to change the code so that all that side session run in a different thread (in case that would help) or to refactor the whole service so that only one transaction can be open at any time.
Actual Question starts here
Is there any possibility to start multiple simultaneous sessions/transactions in one Thread? If so, what would I have to do, to tell hibernate to do that? If this is not possible what way of accomplishing a similar behavior would you suggest?
Code snippet I use to create the sessions
Session session = sessionFactory.openSession();
CustomSessionWrapper dpSession = new CustomSessionWrapper(session, this);
if (!session.isClosed() && !session.getTransaction().isActive()) {
session.beginTransaction();
}
The code worked before I upgraded hibernate so the problem should not be in the CustomSessionWrapper or any other custom class.
Thanks a lot in advance!
I have a Local Cache which is caching data from a web service. If suppose the web service is down, then definitely there is an exception thrown. I would like to handle this exception and return previously cached values from the method. Can any one tell me, Does Gemfire has any such exception handling feature to handle such exceptions? Im using annotation based caching.
I'm assuming you are referring to the Spring #Cacheable capability. With that framework, the cache is checked first so, if there is an answer in the cache it will not call the web service at all (so it won't matter whether it is up or down).
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