Wildfly treating concurrency management as transactional - java

I had a class that looked like this:
#Singleton
#ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
#Lock(LockType.WRITE)
#AccessTimeout(value = 20, unit = TimeUnit.MINUTES)
public class MyClass{
public void someLongRunningQuery(){
}
}
However, this would fail with:
org.jboss.resteasy.spi.UnhandledException: javax.ejb.EJBTransactionRolledbackException: Transaction rolled back
I was able to resolve this by adding this annotation.
#TransactionTimeout(value = 20, unit = TimeUnit.MINUTES)
My question is - why is jboss treating this method as a transaction? My understanding is the concurrency management and transaction management are different things.

Transaction timeout handling is not defined in EJB spec and JBoss uses a separate transaction management module to do that. Your example points at a REST access to your singleton - is the Singleton also a REST endpoint or is it invoked from some REST endpoint bean? Just a couple of ideas:
If you have a REST endpoint that injects your singleton and invokes the long running op, isn't it by any chance a #Stateless bean? EJB beans are transaction enabled by default, therefore if a client(REST endpoint) initiates a transaction(it does by default - #TransactionAttribute(REQUIRED)), your singleton will also participate in the same transaction, but because its invocation takes longer than the default transaction timeout value(300s) it causes transaction rollback. If you do not need a transaction on the rest layer, try disabling it with #TransactionAttribute(NOT_SUPPORTED)
If you invoke this long running op from REST layer, wouldn't it be better to use #Asynchronous and return some kind of request/job handle to the client, so that it can query the status of the operation instead of waiting and blocking while it finishes? Keep in mind that EJBs are pooled resources, therefore invoking this long op multiple times can drain your pool and cause acquisition timeouts.

Related

Multi-threading Spring Transaction

Assume that we go inside a method and start a transaction in main thread. In this method, there are some async methods so we created 2 more threads inside this method;
Thread 1 --> SubMethod1 --> Saving (t=1)
^
|
MainThread --> MainMethod --> Saving (t=3)
|
v
Thread 2 --> SubMethod2 --> Exception while saving (t=2).
Since thread 2 gets an exception, I want to rollback all transactions done by other threads. However, although transactions owned by main thread an Thread 2 can be roll-backed, I cannot roll-back thread 1 work.
I am using Spring/Hibernate, so do you have any idea to manage this and how to apply?
Thanks
From Professional Java for Web Applications by Nicholas S. Williams
The transaction scope in Spring is limited to the thread the transaction begins in. The transaction manager then links the transaction to managed resources used in the same thread during the life of the transaction. When using the Java Persistence API, the resource you work with is the EntityManager. It is the functional equivalent of Hibernate ORM’s Session and JDBC’s Connection. Normally, you would obtain an EntityManager from the EntityManagerFactory before beginning a transaction and performing JPA actions. However, this does not work with the Spring Framework model of managing transactions on your behalf. The solution to this problem is the org.springframework.orm.jpa.support.SharedEntityManagerBean. When you configure JPA in Spring Framework, it creates a SharedEntityManagerBean that proxies the EntityManager interface. This proxy is then injected into your JPA repositories. When an EntityManager method is invoked on this proxy instance, the following happens in the background:
➤➤ If the current thread already has a real EntityManager with an active transaction, it delegates the call to the method on that EntityManager.
➤➤ Otherwise, Spring Framework obtains a new EntityManager from the EntityManagerFactory, starts a transaction, and binds both to the current thread. It then delegates the call to the method on that EntityManager. When the transaction is either committed or rolled back, Spring unbinds the transaction and the EntityManager from the thread and then closes the EntityManager. Future #Transactional actions on the same thread (even within the same request) start the process over again, obtaining a new EntityManager from the factory and beginning a new transaction. This way, no two threads use an EntityManager at the same time, and a given thread has only one transaction and one EntityManager active at any given time.
If you were not to use Spring MVC then you would have gotten the session using SessionFactory in Hibernate. Hibernate Sessions represent the life of a transaction from start to finish. Depending on how your application is architected, that might be less than a second or several minutes; and in a web application, it could be one of several transactions in a request, a transaction lasting an entire request, or a transaction spanning multiple requests. A Session, which is not thread-safe and must be used only in one thread at a time, is responsible for managing the state of entities.
This post https://dzone.com/articles/spring-transaction-management-over-multiple-thread-1 appears to cover the issue quite well and mentions a project that is doing something similar.

How to do Distributed Transactions XA in Spring and GlassFish 5?

I am trying to create a transaction comprising two REST web services, whose data source point to the same data base. The first service, named 1, invokes another web service named 2 using Spring RestTemplate.
To implement the transaction I am using a JNDI connection pool, the MySql JDBC driver (version 5.1.35), JTA, XA, Spring and the GlassFish 5 AppServer.
Now, I have downloaded the maven dependencies in the Spring project, defined a configuration class using JtaTransactionManager, and configured the datasource and JTA properties in an application.yml file, like in the following code:
Configuration class:
#Configuration
#EnableTransactionManagement
public class Transacciones {
#Bean
public PlatformTransactionManager platformTransactionManager(){
return new JtaTransactionManager();
}
}
application.yml file
spring:
datasource:
jndi-name: jdbc/Prueba
driver-class-name: com.mysql.jdbc.Driver
jta:
enabled: true
I configured the JNDI datasource in GlassFish 5 defining a "JDBC Resource" named jdbc/Prueba in the "Connections pools" page using a javax.sql.XADataSourcedatasource named pruebaXA:
In the control layer of the web service 1, the method calls the service 2 using the RestTemplate class of Spring Framework:
Service 1 code:
#RestController
#RequestMapping("/servicio")
#EnableTransactionManagement
public class a {
#Autowired
private JdbcTemplate objJdbcTemplate;
#Transactional(rollbackFor = RuntimeException.class)
#GetMapping("/1")
public Integer getValor(){
try{
int numero;
int n=50;
RestTemplate restTemplate = new RestTemplate();
Integer intRes1;
Integer intRes2;
numero = (int) (Math.random() * n) + 1;
intRes2 = restTemplate.postForObject("http://localhost:8080/servicio2-1.0-SNAPSHOT/servicio/2",numero,Integer.class);
intRes1=objJdbcTemplate.update("INSERT INTO A VALUES(" +numero + ")");
return numero;
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
Service 2 code:
#RestController
#RequestMapping("/servicio")
public class a {
#Autowired
private JdbcTemplate objJdbcTemplate;
#Transactional(rollbackFor = RuntimeException.class)
#PostMapping("/2")
public Integer getValor(#RequestBody Integer intNum){
try{
Integer intRes;
intRes=objJdbcTemplate.update("INSERT INTO B VALUES(" + intNum + ")");
return intRes;
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
If the two services work without errors, there is not problem. However, when the service 1 falls, the service 2 does not know about the error and does not do the rollback.
I do not know if I need to configure another feature/option in the GlassFish 5, or in the Spring program.
I have read that in Spring only needs a JtaTransactionManager bean and the framework performs all the work related to configure and use JTA-transactions.Spring and JTA
JTA
Now, if you still need to use JTA, at least the choice is yours to
make. There are two common scenarios: using JTA in a heavyweight
application server (which has all the nasty disadvantages of being
tied to a JavaEE server), or using a standalone JTA implementation.
Spring provides support for JTA-based global transaction
implementations through a PlatformTransactionManager implementation
called JtaTransactionManager. If you use it on a JavaEE application
server, it will automatically find the correct
javax.transaction.UserTransaction reference from JNDI. Additionally,
it will attempt to find the container-specific
javax.transaction.TransactionManager reference in 9 different
application servers for more advanced use cases like transaction
suspension. Behind the scenes, Spring loads different
JtaTransactionManager subclasses to take advantage of specific, extra
features in different servers when available, for example:
WebLogicJtaTransactionManager, WebSphereUowTransactionManager and
OC4JJtaTransactionManager.
So, if you’re inside a Java EE application server, and can’t escape,
but want to use Spring’s JTA support, then chances are good that you
can use the following namespace configuration support to factory a
JtaTransactionManager correctly (and automatically):
Alternatively, you can register a
JtaTransactionManager bean instance as appropriate, with no
constructor arguments, like this:
#Bean public PlatformTransactionManager platformTransactionManager(){
return new JtaTransactionManager(); } Either way, the end result in a JavaEE application server is that you can now use JTA to manage
your transactions in a unified manner thanks to Spring.
Thanks for your help and time.
How to do Distributed Transactions XA ?
If you invoke first a REST or web service and then another one, both operations will not be part of a transaction. To form a transaction, these operations must "start" a transaction or be "joined" to an existing one. To execute that transaction, your program must interact with a transaction monitor (TM) such as the proposed by AT&T/Oracle Tuxedo (released in the 80s), the X/Open XA standard (released in the 90s) and the JTA-based systems.
Note how the TM-based transaction works:
A transaction using XA datasources is basically a program that invokes database operations on two different databases. The same program (e.g. invoking methods in one or more bean) starts the transaction, performs some operations on a database and performs other operations on another database. If one of the operation fails, the other operations are not performed or are rollbacked.
A transaction using XA datasources and JTA-enabled components is basically a program that combines operations on one or more databases with other transaction-enabled operations. For instance, you can combine operations on a database with operations on a content repository or a network-based file system. You can define transactions that, when a database operation fails, does not perform or rollbacks operations on the file system. Non-transactional applications such as COBOL-based programs can be integrated in a transaction by defining operations and compensations in the transaction monitor.
A transaction integrating web-services requires an special handling. For instance, there is a proposal for webservice transactions such as the WS-Transaction and WS-Coordination specification. There is a coordinator that works like the transaction monitor. The software must invoke the coordinator to start the transaction. Each participant in the transaction reports if each operation is successful or failed. The coordinator invokes the other operations or invokes the compensations according to the results.
Nowadays, there are some proposals for software architecture that do not rely on TM-based transactions. Designs based on CQRS and Event Sourcing implement transactions using the Sagas design pattern. If you are interested on defining a transaction-like operation that invokes two REST services, you may consider to avoid the XA/JTA and program a Sagas.
How to do Distributed Transactions XA in Spring and GlassFish 5?
You may check many tutorials in the Internet. For instance,
a tutorial that shows you three use cases: one updating two databases, one combining database operations and outgoing JMS-messages, and another one combining incoming JMS messages and database operations.
a video describing how to manage distributed transactions in Spring with JTA
and the documentation from the Spring Framework.
If the two services work without errors, there is not problem. However, when the service 1 falls, the service 2 does not know about the error and does not do the rollback.
That is the correct behavior. When you invoke a REST/webservice, the operations performed by that REST/webservice do not join to the transaction. If the invoking service fails, the invoked service will not notice it and will not rollback their operations in the database.
I do not know if I need to configure another feature/option in GlassFish 5, or in the Spring program.
No. You only have to configure the XA-datasources. Spring will use your configuration class and annotations to join automatically into a transaction the operations performed by your application on these datasources. For instance, if you have a bean that invokes multiple methods that performs operations on one or more XA-datasources, these operations will join into a transaction.
However, when you invoke a method in REST/webservice in another application, the database operations performed by that REST/webservice will not join to the transaction.
rest web services (http based) are non-transactional by their nature (they are http based). you have made each method/operation transactional, but they do not share any state between the resources (rest operations). generally - you can have XA transactions over database or mesaging, not over http calls.
intRes2 = restTemplate.postForObject("http://localhost:8080/servicio2-1.0-
SNAPSHOT/servicio/2",numero,Integer.class);
Calling a remote web service is without any transaction context. If you need to maintains transaction between services, call the secord service as EJB (or as an injected managed bean)
Basically: using http-based rest services - forget any transactions between them. The protocol (HTTP) is not built for that.
The only thing I've seen transactional is SOAP with WS-RM extension (SOAP with reliable messaging)., however it is not very easy to setup (read: it can be nightmare to make it work when you don't know what are you doing) and not all WS frameworks support it.
When you really need reliable delivery between web services, there's a way. what is comonly used to achieve assured delivery is messaging with idempotent services (https://en.m.wikipedia.org/wiki/Idempotence) with store-and-forward pattern. In simple terms - service 1 stores a JMS message to a queue and there's a processor (MDB) which calls service 2. (yes, calling a remote web service it may happen that the service 2 will receive a message multiple times. Indempotency is a way how to deal with it.)
Transactions across REST services are supported by http://www.atomikos.com
Cheers

Accessing stateless EJBs in PreDestroy method of Singleton

I have a problem accessing stateless EJBs in the preDestroy method of an singleton. I need to log the shutdown of the application server in an database table.
This is what the singleton looks like:
#Startup
#Singleton
public class ServerShutdown {
#EJB
TableFacade tableFacade;
#PreDestroy
private void shutdown() {
TestEntity e = tableFacade.find("test");
//do something
}
}
Here's example code of the stateless bean:
#Stateless
public class TableFacade {
...
public TestEntity find(String test) {
Query query =
getEntityManager().createNamedQuery("TestEntity.namedQuery");
return (TestEntity) query.getSingleResult();
}
}
If the server is shutting down, the preDestroy method is accessed and the EJB method is called. But during the call, the server seems to force the shutdown process and cancels the calling of the EJB method.
I'm using Java EE 6, JDK 1.8, EJB 3.1, eclipselink 2.5.2.
Thanks in advance
The #predestroy should only do ejb resource cleanup, such as connection, variable etc...
Your problem has to do with the transaction context, infact from the spec:
The PreDestroy lifecycle callback interceptor methods for stateless
and stateful session beans execute in an unspecified transaction
context.
And then:
For example, it would be wrong to perform database operations within a
stateful session bean’s PostConstruct or PreDestroy lifecycle callback
interceptor methods and to assume that the operations are part of the
client’s transaction. The PostConstruct and PreDestroy methods for
stateful and stateless session beans are not controlled by a
transaction attribute because handling rollbacks in these methods
would greatly complicate the session instance’s state diagram.
So, it is not explicitly forbidden, but you are warned that things may go wrong.
According to the ejb 3.2 spec, singleton beans are allowed to access ejb's in their pre destroy method. See section 4.8.6 Table 3. If a singleton bean needs to access another singleton bean, then it must declare its dependency using the #DependsOn annotation. The example provided by the original poster should work.

declarative transaction vs programmatic transaction

If we go with programmatic transaction, we write
Session session=sessiongFactory.openSession();
Transaction tx=session.buildTransaction();
And for a session we can build as many transaction we want.
So, We have first session object than we get Transaction Object.
While in Declarative Transaction,If we declarative #Transaction annotation at service level.
"When this Service Method will be called,Transaction will be Open" so here there is not any inforamtion about Session.
Then in Dao we write
Session session=sessiongFactory.getCurrentSession();
Here we have first Transation then Session,
Can any one please help me in understanding ,How spring manages this Declarative Transaction.
According to documentation method sessiongFactory.getCurrentSession() obtains the current session, and"current session" means controlled by the CurrentSessionContext impl configured for use.
Documentation also provides this explanation for backwards compatibility: if a CurrentSessionContext is not configured but a JTA TransactionManagerLookup is configured, this will default to the JTASessionContext impl.
JTASessionContext implementation will generate Sessions as needed provided a JTA transaction is in effect. If a session is not already associated with the current JTA transaction at the time currentSession() is called, a new session will be opened and it will be associated with that JTA transaction.
With Spring declarative transaction management you can apply #Transactional at both method & class level.
It is enabled via AOP proxies. The combination of AOP with transactional metadata yields an AOP proxy that uses a TransactionInterceptor in conjunction with an appropriate PlatformTransactionManager implementation to drive transactions around method invocations.
Conceptually, calling a method on a transactional proxy looks like this…
When using proxies, you should apply the #Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the #Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings.
All transactions are associated with the session. Transactions are initiated on the service layer but they have to be associated with a session to be committed. First transaction completes then session is closed. A session can also span several transactions. If you are using hibernate, spring uses hibernate managed transaction manager which is responsible for associating transactions with hibernate session.
Spring transaction management abstract the transaction handling and decouples the transaction demarcation logic (e.g. #Transactional) from the actual transaction manager (e.g. RESOURCE_LOCAL, JTA).
The problem with programmatic transaction is that you tie your application code to the transaction management logic. On the other hand, Spring allows you to switch from JpaTransactionManager to JtaTransactionManager with just some configuration (no need to change the application code).
Spring only creates a transaction context that's used by the inner TransactionInterceptor to execute the actual transaction management hooks.
For RESOURCE_LOCAL, transactions are handled through the JDBC Connection commit() and rollback() methods.
For JTA, transactions are handled through the JTA UserTransaction commit() and rollback() methods.
Everything is explained in the docs. You may also want to take a look at Spring integration with ORM.
Basically, Spring creates a proxy which intercepts the transactional methods invocation and starts the transaction before delegating the call to the target method, and ends the transaction when the target method returns.

Will Spring estabilish connection to DB, when I use transacional bean in non-transacional?

Good day, guys!
If I have non-transactional bean(BannerSizeServiceUntransact), which uses transactional bean(bannerSizeService), will Spring estabilish connection to DB, when I use non-transacional bean?
(I have many refused connections to PostgreSQL in log. I belive my logic does;t create new connection on each request, but may be I wrong.)
#Repository
public class BannerSizeServiceUntransactImpl implements BannerSizeServiceUntransact {
#Resource
BannerSizeService bannerSizeService;
public List<BannerSizeVO> sizesByType(String type) throws BannerServiceException{
return bannerSizeService.sizesByType(type);
} }
#Repository
#Transactional
public class BannerSizeServiceImpl implements BannerSizeService {
....
}
Yes, Spring will establish a database connection even when you're using beans that aren't marked #Transactional, so that's not the cause of your refused connections.
What's going to happen in this scenario is that when you invoke the call to bannerSizeService.sizesByType(type), Spring will start a new transaction, and when control returns to BannerSizeServiceUntransact.sizesByType(), it will end. So if BannerSizeServiceUntransact.sizesByType() did other database calls before or after the call to bannerSizeService.sizesByType(type), those calls would happen in separate transactions, one per DB call. (Not annotating a Service as #Transactional doesn't mean that transactions aren't used, just that they only span a single database call.)
Also note that if the method that calls BannerSizeServiceUntransact.sizesByType() was marked #Transactional, then the transaction started there will carry over all of the code you've shown here, because that transaction will start when that higher-up method is called and will end when it ends, and all of the code here will have executed while it was in effect. Not annotating something as #Transactional doesn't forbid its participation in an existing transaction, it just doesn't require the initiation of a new one.
Also, keep in mind that #Transactional controls transactions. Spring might end up making a new connection for each transaction it opens, or using only one and reusing it for each transaction, or rotating through a pool of connections (resulting in more than one but fewer than N connections for N transactions). It's guaranteed that if Spring talks to the database, there will be a connection in use, but you can't guarantee how many will be used over N calls simply by your #Transactional annotations. (Though of course you can set settings in your Spring config that might impact the number used, e.g. specifying a connection pool with a max size of 1.)

Categories