can/does global transaction span multiple threads? - java

We are using JTA to manage global transactions in servlet context. Additionally, some of the servlet threads are invoking asynchronous beans. Currently, I have designed it in a way so that the asynchronous bean (Work Manager) gets its own transaction.
It's my understanding that two threads can participate in the same XA transaction. But if I start using the transaction created by the servlet, for the asynchronous bean, will that block the servlet thread until all participant have committed or rolled back? Both the servlet and the async bean can commit and rollback.
The app server is WebSphere, and we are NOT using Spring.
Your response is appreciated.

Using the same transaction both for the servlet thread and an asynchronous worker conflicts somehow with the general idea of messaging. Messaging is a means to decouple, whereas a transaction keeps things tightly together.
In other words, if you want a worker to use the same transaction, I would not implement the worker in an asynchronous way.
As for two threads participating in the same XA transaction, this might not be supported, look here for details. Even if it worked, it could be troublesome to share resources over a thread context generally speaking (file handles, connections, transactions whatever).
As for the servlet thread, whether it blocks: I have never tried it (for the above reasons), but I assume that it does not block: You would have to wait/poll for your async workers, until they have finished (or failed). Otherwise the servlet just reaches your commit statement.

Related

Spring's #Async managing threads

I'm struggling with asynchronous processing in Spring. I've decided to use #Acync together with #EnableAsync and ThreadPoolTaskExecutor.
Is there any mechanism responsible for thread's hanging coming together with Spring's #Async? The Async method calls few external resources with RestTemplate and I should probably somehow protect against hanging a thread.
The only possibility of hanging thread with #Async is if request to any external resource goes to hang state due to some network or resource issue.
The solution would be, provide connection timeout for each external resource call.

How do I timeout a blocking call inside an EJB?

I am in the process of developing an EJB that makes 10+ calls to other components (EJBs, Web services, etc.) as part of it's business logic. In my case, performance is a huge concern. This EJB will be servicing a few million requests a day.
My question is: For each of those 10+ calls, how can I enforce a timeout?
I cannot wait more than 'n' seconds for any one of the calls to return. If a call takes longer than 'n' seconds, I will use a default response for processing.
I would normally use a Executor to solve this problem but, from what I understand, one shouldn't spawn threads from within an EJB as it may potentially interfere with the EJB's lifecycle.
how can I enforce a timeout?
The ejb3.1 specification provides the possibility to set a timeout using #AccessTimeout annotation that applies for serialized client calls that have to wait when an Session Bean instance
is busy executing a previous request.
Clearly (and explicity described in the specification) this applies to StateFul and Singleton session bean, although it could be implemented for Stateless in the case the bean pool run out of available instances.
Notice, once the client-invoked business method is in progress this timeout no applies.
Other possibility that is not part of the specification but, is supported by several servers (see JBoss example) is to define a timeout at the remote client side. If the client invocation
takes longer than the configured timeout, the client will be informed, however, the server execution will not be interrupted which it is not good enough.
Set a transaction timeout neither is a good option because there is no guarantee the thread that executes the business logic will be interrupted when the transaction timeout expires.
I would normally use a Executor to solve this problem but, from what I understand, one shouldn't spawn threads from within an EJB..
Instead you could use ManagedExecutorService class that is an Executor extension suitable to use within a EJB Container.
Aditionally, to implement asynchronous call within an EJB, take a look at #Asynchronous annotation, which provides a high level abstraction to solve the multithreding issue you are facing.
Cancel() method from Future class, allows you to interrup a thread's execution if you consider that the process has taken too long.
since you are not providing much detail of your environment:
use bean managed transactions and set the transaction timeout
EE7: provides an managed executor service
EE6: custom executor service as a JCA connector

JDBC Transactions behaviour while tomcat redeploying

What happens when I have a number of active JDBC transactions and a redeploy hits the web application?, I searched the Tomcat docs but didn't find anything related.
For example: 30 customers have a shopping cart with items and they save the order at the same time, so a transaction is started, and a redeploy is triggered
What happens? Do the all items get correctly saved? or At time of redeploy all active transactions are discarded? or Tomcat waits the redeploy command till all the transactions are commited?
I'm using Tomcat JDBC Pool
The key point to keep in mind is where is the connection pool instantiated?
If you define the connection pool at the Context level, then the connection pool is created when the context is created, and should be destroyed with the context too.
Redeploying an application in Tomcat requires shutting down the current context and then starting up the replacement context. So in that case I would expect that the behaviour will be determined by the value of defaultAutCommit or the effective value of autoCommit for each transaction. If true then shutting down the resource should commit the transactions. If false then, just like with any InterruptedException your exception handling path should trigger rollback, or worst case the connection shutdown should rollback the transaction.
What you really want to examine is how Tomcat shuts down an application. I have not looked at the actual code in detail, but my understanding is that first it stops sending requests to the "old context". Then once all the pending responses have completed, the ServletContextListeners get called to notify of shutdown, once they and their Filter and Servlet counterparts are completed, the context is effectively shut down and the resources can be cleaned up. What complicates things, IIRC is that Tomcat does not wait for ever for responses to complete and may start interrupting the handler treads, or just plain switch over to the new context without waiting for the old or to finish tearring down.
I annot remember which container (jetty/tomcat) supports starting up the new context and then switching request handling over only once the new context is ready to give zero downtime switch over... The key issue with that is you need a persistent session store and an applcation that can run on a cluster safely to be able to use such a deployment mode.
In short, your applcation will be shutdown gracefully before the new context starts, so I would expect transactions to either complete or recipe an InterruptedException at which point your try...finally blocks should kick in

how the Transaction concept is implemented in EJB

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

Threads in Spring

I have a Web application using spring and hibernate and struts (it runs on Tomcat)
The call sequence is something like this...
Struts action calls spring service bean which in turn calls Spring DAO bean. The DAO implementation is a Hibernate implementation.
The question is
Would all my spring beans be running in the same thread ?
Can I store something in the ThreadLocal and get it in another bean?
I am quite sure this would not work in Stateless Session Bean.
The EJB container can (or will) spawn a new thread for every call to the session bean
Will the spring container do the same? i.e. run all beans in the same thread ?
When I tried a JUnit test - I got the same id via Thread.currentThread().getId() in the Test Case and the two beans- which leads me to believe there was only one thread in action
Or is the behavior unpredictable?
Or will it change when running on Tomcat server ?
Clarification
I do not wish to exchange data between two threads. I want to put data in the ThreadLocal and be able to retrieve it from all beans in the call stack. This will work only if all beans are in the same thread
Spring doesn't spawn the threads. Tomcat does. Spring is just creating and wiring up the objects for you.
Each request from the browser is processed in one request. It is Tomcat that handles the request. It is Tomcat that creates the thread to process the request.
Assuming you have just created a singleton bean in Spring called "X". Then the same instance of X is used by all requests.
The Spring beans don't live in a thread. They are just allocated on the heap.
Would all my spring beans be running
in the same thread ? Can I store
something in the ThreadLocal and get
it in another bean?
AFAIK for the components you mentioned (service bean, DAO bean - i guess they are plain spring beans), Spring does not spawn a new thread. I do not understand your use case (ie, exchanging data between two threads).
For most webapps, a new thread is spawned for each new request, and if you want to share data between two requests you normally:
- use the get/post parameters to pass the data
- use the session to share data
To answer your question, I'm pretty sure the spring container does not spawn threads for most components.
Yes, you can do this. The same thread will be used to execute your action so the ThreadLocal will work. Typically, the same thread is used for the stateless session bean as well, assuming it is running in the same app server instance. I would not depend on this though, as it is probably vendor dependent.
We use this technique to access the callers identity anywhere in the code. We use session beans and jms as well, but explicitly pass the information between containers and set the ThreadLocal at each entry point. This way it doesn't matter if the bean (session or mdb) are local or not.
In addition to all the other answers, I will just add the following:
Normally the only reason to switch threads is because of some requirement for parallellity. Since this normally does not come for free in terms of complexity, you will usually be clearly informed when this happens.
Switching threads within what appears to be a single-threaded processing of a request is actually extremely complex. This will normally only happen at one place in a container, and this is usually handled by tcp/ip socket readers that receive the request from the external clients. These reader threads usually determine which thread(pool) should process the request and forward the request to that thread. After that the request stays with that thread.
So normally the only thing that will/can happen is that additional threads get created for parallelity or asynchronous processing (like JMS).

Categories

Resources