Spring #Transactional timeout not timing out - spring

I have set transaction timeout in my application as #Transactional(propagation=Propagation.REQUIRED,timeout=30)
ActiveMQXAConnectionFactory and Oracle XA Datasource are two resources of my Distributed transaction. after reading a message from queue my transaction begins and while processing the application is taking more than 30 seconds and still transaction is not timed out. Only when committing the transaction its throwing timeout exception. I wanted immediately after 30 seconds the transaction should time out and throw the exception and make that thread available to consume another message from queue. Is this possible?

Without seeing your configuration it will be hard to say. If you are just adding an #Transactional, it is not going to do anything. You going to need both an EntityManager and a TransactionManager, then you need to turn on annotation based transaction management, and Spring needs to be controlling your datasource if I recall correctly.
Another, probably unnecessary side note, #Transactional will only work on public methods. Spring will proxy your method in order to manage the transaction and Spring can only proxy public methods. Also, it will only be able to work on calls from another class to that method, if you are calling that method from another method inside the same class, Spring cannot proxy either, thus no transaction management. Spring is sneakily deceptive here.
#Service
public class A{
#Autowired
Datasource datasource;
#Transactional
public void save(){
datasource.doStuff();
}
public void callSave(){
save();
}
}
#Service
public class B{
#Autowired
A a;
public void callSave(){
a.save();
}
}
Here, if a.save() is called from a.callSave(), no proxy will occur, thus you will have no transaction management. But in the exact same application, if you call b.callSave(), you will have transaction management, since Spring can then proxy the method call to a.save().
Are you using Spring Boot or vanilla Spring? We can probably give you more of a direction if you divulge that.
Hopefully that helped a bit!

Related

Handling Datastax Java driver CqlSession in Spring Boot

Datastax Java driver documentation says to create a single instance of CqlSession for your Spring Boot application as building a session is a costly operation.
I want to manage the CqlSession in an effective way in Spring Boot such that CqlSession instance should be closed and not kept open in order to free underlying resources(TCP connections, thread pools…).
Driver documentation URL: https://docs.datastax.com/en/developer/java-driver/4.13/manual/core/
Here is my CqlSession Instance class. I use the Cqlsession instance to run Cql queries all over my Spring Boot application by injecting it as a Dependency in my #Service and #Repository classes.
Also I never close my Cql session manually but let the Spring handle it using #PreDestory annotation. Should session be closed as soon as a cql query is executed or should I allow spring to handle it as mentioned in the below code? I have realised that doing so, it takes a latency about 1-1.5 seconds for building cqlsession again and queries are ran super slow due to this.
#Configuration
public class CqlSessionInstance {
private CqlSession session;
#PostConstruct
private void initSession() {
getSession();
}
public final CqlSession getSession() {
if(session == null || session.isClosed()) {
session = CqlSession.builder().build();
}
return session;
}
#PreDestroy
public final void closeSession() {
if (session != null && !session.isClosed()) session.close();
}
}
Let me know if there are better ways to manage a CqlSession in Spring Boot
In my opinion, I suggest that you close the CqlSession yourself, since you know when you are executing as a specific request, and you know when to close it.
If you use the annotation #PreDestroy, you are depending on the Spring Life Cycle Management and as such it is hard to determine "when" exactly your component will be destroyed, and as such your session closed.

SpringBatch #Async method not working in persistent layer (JPAItemWriter)

SpringBoot Application with SpringBatch and JPA, without #Async all working fine but with #Async added in the REST API the job is completed but JPAItemWriter is not persisting the objects in the DB. looks like Transactional problem as am getting this exception.
Transaction Manager [org.sringframework.batch.support.transaction.ResourcelessTransactionManager] does not support transaction suspension.
I tried with different approaches like changing Propagation.Requires_New (Required, Supports) but nothing works, tried searching all the forums but no luck.
#Service
public class SampleWriter extends JpaItemWriter<TestEntity> {
#Autowired
EntityManager entityManager;
#Transactional(readOnly=false, propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
#Override
public void write(List<TestEntity> entities) {
this.doWrite(entityManager, entities);
}
}
It seems that you are configuring and using Spring Batch in a wrong way.
Firstly, it is using the default BatchConfigurer which the TransactionManager is ResourcelessTransactionManager that is mainly use for testing or acts as a "no-op" TransactionManager for the batch job that does not require any transaction which is definitely not your case now.
Secondly, Spring Batch will internally take care of managing the transaction boundary for processing each chunk , you do not need to extend JpaItemWriter and control the transaction behaviour using #Transactional by yourself.
So , read this section for how to configure Spring Batch , especially the part related to BatchConfigurer
On the other hand if you are using Spring-boot , it should already configure a JpaBatchConfigurer for you.

Using PersistenceContext in a Quartz Job

We're using Spring 3.1, JPA (via Hibernate) and Quartz. Typically we interact with the DB via #PersistenceContext annotation on Service beans, and either SpringMVC controllers, or GraniteDS-managed service invocation.
I'm working on writing a Quartz job that needs to interact with the database. I've tried everything I can find to get this working. I tried passing in a Spring-managed component (annotated with #PersistenceContext and #Transactional) via the jobMap, the call to entityManager.persist(o) executes, but nothing happens in the database. I also tried similar to this answer, creating a factory class to call autowireBean() on the job object. I set up the job class like so:
public class CreateAlertJob implements Job {
#PersistenceContext
EntityManager entityManager;
#Override
#Transactional
public void execute(JobExecutionContext context) throws JobExecutionException {
SomeEntity entity = new SomeEntity();
entityManager.persist(entity);
}
}
Same result, the method executes but the database is unaltered. I found this blog post which references a GitHub project. There he is using JpaInterceptor to establish a Hibernate session, but this uses the DAO pattern and I'd like to stick with using #PersistenceContext.
Clearly there is something about the Quartz thread that is preventing this from working properly? I'm about out of ideas and considering making a web service call to a SpringMVC controller just to get this working.
Since your CreateAlertJob is not created by Spring, #Transactional in it doesn't take effect.
You have the following options:
Delegate actual work to Spring bean and put #Transactional there
Use programmatic transaction management
Use AspectJ-based AOP implementation instead of Spring default implementation (but it would be overkill for such a simple problem)

JPA EntityManager Session Lifecycle Close Event

When using the Hibernate implementation of JPA and managing those resources using a Spring datasource, when does the EntityManager session get closed? For example I have the basic pattern below that has the Spring service layer calling a Spring DAO layer (#repository). The DAO repository autowires the PersistentContext's EntityManager and performs the DB operation. My question is when is the EntityManager session closed, after the getData Service method finishes? I'm asking this question as I'm trying to see how long the hibernate L1 cache will be around and since its directly tied to the EntityManager session...
#Service
public class TestService{
#Autowired
private dataDAO;
#Transaction
public List getData(Long id){
return dataDAO.getDate(id);
}
}
By default, spring is releasing the session at the end of the transaction. In this case, the session will be release at the end of the getData method. The first level cache (L1) is bound to the actual transaction and is cleared as soon as the transaction is terminated.

Relation betweenn hibernate and spring

I have a question about spring + hibernate
I always use hibernate for my develeppoment, I generate images of the tables and the class DAO
then at logic metier I make simple calls to these methods dao ....
for exemple UserDao=new UserDao () then userdao.persist() ...
Now I have intgret spring, and I do not yet understand ..
1
what is the plus made ​​by him knowing that he is also making calls
has dao Service (the writings that manually) it does not generate the
class dao with hibernate
2
is that with spring I would not worry about manage session for
example open session, close session commit() ...
thank you in advance I would like to have an idea Ccool:
At its core, Spring is a dependency injection framework. This means that instead of doing
public class MyService
private MyDao dao;
public MyService() {
dao = new MyDao();
}
}
You can do
public class MyService
private MyDao dao;
#Autowired
public MyService(MyDao dao) {
this.dao = dao;
}
}
And Spring will automatically call the constructor and inject an instance of MyDao. The main benefit is that the code is easily unit-testable.
On top of that, it allows injecting proxies instead of the actual implementations directly. These proxies will indeed handle the transaction management for you, and more (exception translation, security checks, etc.).
So instead of explicitely opening, committing and rollbacking transactions, you would simply annotate a service method with #Transactional, and Spring would open, commit/rollback the transaction. And the transaction context would automatically propagate to the nested service calls.
This short answer is only to give you an idea. To learn more, read about dependency injection, and read the Spring documentation.
Use Spring annotations like #Service for service classes, #Repository for Dao classes and #Controller for action controllers. Use of #Transactional on service class or methods is suffice to carry out transactions.

Resources