JPA and JTA synchronization - java

I'm developing a JPA provider that uses Mongo Driver.
I know that there are Mongo providers for JPA but I need to have more control in what's happening. I reached the point where I need to create a mechanism to synchronize JPA and JTA (Narayana), but I'm not sure how can I do it, I know that javax.transaction.Transaction has method where you register a javax.transaction.Synchronization that has two methods beforeOperation and afterOpertation. So my question is,
where do I perform my CRUD operations where do I call the commit of JPA when JTA commit is called? Should I perform the operations on those methods?
Thank you for your help and time.

Related

JTA for single database

I am just learning JTA and can't understand if I should use it if I have only one database. Currently I use hibernate 5 as JPA provider and if I need to use one transaction between methods I just pass EntityManager as argument.
However, I don't like this method as I need to remember if transaction is opened or not. I would like to find any library that will help me to control transactions (but without Spring) in SE environment. So, should I use JTA in my situation or should I use something different?
Normally when talking about JTA , it refers to the distributed transaction across multiple systems (e.g. across two databases , one database and one JMS compliant message broker). If you only have one database , it is not necessary to use JTA transaction although it should also work. Instead, use a local transaction for one database which should theoretically faster than using JTA transaction.
On the other hands , if you are just talking about #Transactional defined in the JTA , which allow you to declaratively control the transaction boundary by annotating it on a method and without passing the EntityManager between methods , you should look into which frameworks support it.
Under the cover , a proxied EntityManager is injected into different classes such that when it is invoked , it will get the actual EntityManager from the ThreadLocal. So every class in the same thread will get the same EntityManager which prevent you from passing the EntityManager around the methods. A new EntityManager instance will be set to the ThreadLocal just before the #Transactional method is executed using some sort of AOP technique.
Please note that #Transcational is nothing to do with the underlying transaction is JTA or local transaction. It should work for both transaction type.
I would use a framework that support #Transactional such as Spring , Quarkus or Micronaut etc , and configure Hibernate to use local transaction but not JTA transaction for single database.

where to define transaction boundries in java (#Service or #DAO level), Any Suggestions

where to define transaction boundries in java (#Service or #DAO level), Any Suggestions
We need to manage transaction between multiple services.
Depending on your persistence technology some kind of transactions might be needed to persist anything at all. Thus you may want a transaction on a DAO-level for e.g. testing the DAO layer. If e.g. controllers have direct access to DAOs you'll need transactions on DAOs, too.
What you may want to do is declaring a transaction on the service-level and the DAO-level reusing a provided transaction.
Read the great spring reference on transactions as well as the spring data reference for ideas.
Usually I recommend to use Transaction in Service, but it depends on....
In case of Service,you will get ability to create batch of actions in the one transaction.
For example start transaction. read, modify more than one entities, update, delete whatever. close transaction.

Locking all the rows used in the Transaction Java

I have a scenario where I use a read on set of tables in a java service.
I've annotated the service class #Transactional.
Is there any possible way to lock the corresponding rows I read, in all the tables I use, in my transaction and release it at the end of transaction ?
Ps: I'm using spring Hibernate, and I'm new to this locking concept.
any material/ examples links would be of much help
Thanks
This depends on the underlying database engine and selected transaction isolation level.
Some database systems do locking for reads, and some use MVCC, which means your updates won't be visible to other transactions until your transaction finishes and your transaction will operate on a snapshot of data taken at the start of the transaction.
So a simple answer is: choose appropriately high transaction isolation level (e.g. SERIALIZABLE) for your needs and a database engine that supports it.
http://en.wikipedia.org/wiki/Isolation_(database_systems)

Spring JTATransactionManager fails to bind Hibernate and JDBC in a single session

I use JTATransactionManager to manage Transactions. One piece of code that I want to wrap with Spring's #Transactional annotation has 2 database calls - one using Hibernate SessionFactory and another a plain JDBC. Both use the same dataSource. Hence, I expect both to be bound by the same Transaction.
But it does not look like one Transaction is used. Instead each opens its own Transaction. What could be the reason for this. ? How do I make sure to use a single Transaction to bind both these operations. ?
I can provide configuration and code if needed.
Make sure in both of your database calls, you use propagation as Propagation.NESTED as
#Transactional(propagation=Propagation.NESTED)
and in the wrapper method, you mention Propagation.REQUIRED orPropagation.REQUIRED_NEW` as
#Transactional(propagation=Propagation.REQUIRED)
or
#Transactional(propagation=Propagation.REQUIRED_NEW)
By doing this, you mention that both DB calls will inherit the transaction boundary of the wrapper method.

Why use an entity manager?

I am using Hibernate to map objects to entities and I have started to use an Entity Manager. This might be a silly question but what actually is the reason for using the entity manager? Previously I would have used a HibernateSessionFactory to get a session and then use that session to pull/push data.
Because the EntityManager is part of the standard - JPA. Theoretically, you can switch implementations (Hibernate, EclipseLink, OpenJPA) if you need to. Apart from alleged portability there isn't such a big difference between the two.
Hibernate implements the JPA standard. In fact, the EntityManager has a delegate, based on the concrete implementation. For Hibernate the delegate is the Session. If you call getDelegate() it will return the current Session.
I've always used hibernate with JPA (EntityManager) and had very rarely had the need to obtain the Session.
EntityManager is a concept of JPA.
You dont need to use JPA with Hibernate at all (in fact, if it's JPA1, I would suggest you dont).
You use an EntityManager when you are using JPA API. Hibernate implementation of EntityManager internally calls HibernateSessionFactory and manages Hibernate sessions for you.
EntityManagers in JPA serve basically the same purpose as Hibernate sessions.

Categories