Is there any way to set transaction isolation level in EJB in its deployment descriptor itself? - ejb-3.0

Is there any way to set the transaction isolation level in EJB in its deployment descriptor itself? Do we have that flexibility?
I meant transaction isolation level. For bean managed transactions we can set the isolation in a resource manager API like JDBC. I was thinking if in any way we can set the container managed transactions isolation level in a deployment descriptor?

The transaction isolation level is a property of the resource that participates in a transaction. It's unrelated to whether the user manages the transaction (Bean Managed Transactions, BMT) or that the container does that (Container Managed Transactions, CMT).
The only thing EJB does is start, propagate and commit or rollback transactions via JTA. What exactly constitutes as a transaction for each resource is up to that resource.
See this answer for a more detailed explanation: How do i set the Transaction Isolation in EJB?

Related

Is it possible to wait transaction lock release with serializable isolation level?

Context:
We've built a JAVA application using spring framework (5.1.8) & spring boot (2.1.6) with the help of Jhipster.
It is a RESTFul application.
Data persistance is done in a PostGRES database managed by Hibernate (5.3.10).
Application constraints:
Because of our context, we have to process most of update transactions in the same order that they happen.
Problem:
All requests are processed by a business function declared as transactionnal (annoted with #Transactionnal(propagation=Propagation.REQUIRED)).
We set the isolation level to SERIALIZABLE to avoid execution of multiple transaction at the same time (concurrency).
However, with this isolation level, we have to manage the transactions repeat for case of concurrency exception.
Is there a way to force to wait transaction lock release before that isolation throws a concurrency exception (serialize access error), like with pessimistic locks ?
We tried to make transaction synchronized but it doesn't work because it seems commits are done outside the transactions.
Any help would be greatly appreciated.

Running Hazelcast put() and replace() calls in the calling thread

Is it possible to force Hazelcast to run put(), replace(), and delete() methods on the TransactionalMap on the calling thread? I want the XA transaction to carry over from writing to Hazelcast to writing to the database in the MapStore, but Hazelcast is queueing the changes to be run on other threads, so they aren't in the same transaction context.
I've got it set up as a write-through persistence, but I see that it's queueing the TxnSetOperation and running them on a separate thread.
This is in a Spring Boot application using the Hazelcast autoconfiguration with a JPA / Hibernate store backing to PostgreSQL.
MapStore operations don't run in the same transactional context. If you want transactional persistent updates with Hazelcast, you need to use XA transactions and not enable MapStore. Then you can set the persistent store as a different XA resource in your context. You can have a check the related section in Hazelcast's reference manual: http://docs.hazelcast.org/docs/latest/manual/html-single/index.html#providing-xa-transactions
Alsparlan's answer is partially correct, but there's no way to enlist a resource in a MapStore with the same transactional context as your actions against the Hazelcast TransactionalMap. The link he provided does NOT talk about this (unfortunately), but the Javadoc for TransactionalMap does:
When using MapStore, the call to any MapStore method is outside the transactional boundary. If you need to have an XATransaction spanning Hazelcast operations and one more other XAResources (such as a database), you should not use MapStore. Instead, enlist both resources in a transaction
I've removed my MapStore usage and wired my Spring Boot repositories directly into my services so I can make my changes to Hazelcast and my datasource in the same service methods inside the same transaction. Along with this solution to declaratively enlisting the Hazelcast XAResource this is working for me now.

Does global tranactions same as XA transactions?

from Spring documentation(http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html):
16.2.1 Global transactions
Global transactions enable you to work with multiple transactional
resources, typically relational databases and message queues. The
application server manages global transactions through the JTA, which
is a cumbersome API to use (partly due to its exception model).
Furthermore, a JTA UserTransaction normally needs to be sourced from
JNDI, meaning that you also need to use JNDI in order to use JTA.
Obviously the use of global transactions would limit any potential
reuse of application code, as JTA is normally only available in an
application server environment.
Previously, the preferred way to use global transactions was via EJB
CMT (Container Managed Transaction): CMT is a form of declarative
transaction management (as distinguished from programmatic transaction
management). EJB CMT removes the need for transaction-related JNDI
lookups, although of course the use of EJB itself necessitates the use
of JNDI. It removes most but not all of the need to write Java code to
control transactions. The significant downside is that CMT is tied to
JTA and an application server environment. Also, it is only available
if one chooses to implement business logic in EJBs, or at least behind
a transactional EJB facade. The negatives of EJB in general are so
great that this is not an attractive proposition, especially in the
face of compelling alternatives for declarative transaction
management.
For me it looks like distributed transaction description(XA).
Am I wrong or Spring really calls XA tranactions as global.

JTA Transaction with multiple participants

I'm having trouble finding a simple example of a JTA transaction spanning multiple resources (e.g. two databases, a database and a JMS queue, etc.)
I've spent a lot of time reading up on this and have working samples of doing a JTA transaction with a JMS queue, and a JTA transaction over a JDBC database driver. I just can't seem to find anything on making both the JMS queue and the JDBC database part of the same JTA transaction.
Can anyone provide a brief sample or a link to something that does demonstrate how to use the JTA API for this purpose?
For a JTA transaction to coordinate amongst JMS and JDBC resources, the following is required:
XAConnectionFactory - a JMS XA-compliant connection factory must be available in JNDI; the specific one to use depends on your application server/container.
XA-compliant JDBC driver - the driver must be XA, most databases provide one, and the connection must support READ_COMMITTED isolation level, anything less won't be sufficient.
Aside from that, if you're using an app server, the container will handle transactions automatically if you're using message driven beans and XA-compliant drivers.
Check these links for exmaples:
http://blog.inflinx.com/2010/04/08/spring-jta-jpa-jms/
http://www.oracle.com/technetwork/java/faq-140431.html#relship_transac

JMS/MDB rollback

We have a application, which reads of JMS and does some database transactions, all as part of one XA transaction..
If we find the message has some problems, we want to rollback the database,
but we don’t want the rollback off JMS to have us read the message again(we don't want the MDB to trigger the entire process one more if rollback was previously initiated).
To be sure I understand you correctly: you have a transactional message-driven bean that performs some actions on database. You still want the MDB to be a part of XA transaction, but you don't want the database actions to influence the state of the transaction in which the MDB takes part in.
That being said, there are two solutions:
If the MDB runs within a container-managed transaction, wrap all the database actions into an EJB with #REQUIRES_NEW annotation — unless they're already all run in such transactional context.
If your MDB is bean-managed, the message delivery is NOT a part of transaction, so it will not be redelivered, no matter what — section 5.4.12 of EJB Core Contracts and Requirements:
When a message-driven bean using bean-managed transaction demarcation uses the javax.transaction.
UserTransaction interface to demarcate transactions, the message receipt that causes
the bean to be invoked is not part of the transaction.

Resources