Is it really good practice to have non-transactional EJB read methods?

This is a very modest question.

There are several articles that indicate that database transactions should always be used, even for simple read operations. Here's an arbitrary example that makes a lot of sense to me: http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions The Hibernate documentation itself also says:

Always use clear transaction boundaries, even for read-only operations.

OK, it seems clear enough. This has always been my assumption, namely: that since transactions will be applied implicitly at the database level in any case in all cases, it is probably best to always declare them explicitly.

Then I read other articles as follows: http://www.ibm.com/developerworks/java/library/j-ts1/index.html#never (note the callout). This article specifically states:

Never say never

At certain points in time, you can start a transaction for a database read operation, for example, by isolating read operations for consistency or by setting a certain transaction isolation level for a read operation. However, these situations are rare in business applications, and if you do not encounter one, you should avoid starting a transaction for database read operations, since they are not needed and can lead to database locks, poor performance, and low bandwidth.

A bit about dead ends and poor bandwidth also makes sense to me.

Conflict advice at the lowest level. This is normal; as a modest application developer, I can come up with my mind here, I think: I prefer the previous advice, perhaps seeing that if this ORM / database combination provides better transaction-free performance in certain critical cases. Please correct me if I am wrong.

Now I am returning to the XA application and transaction server area.

If I have an EJB method that performs read-only operations, is it good practice to always declare it transactional (following the spirit of the Hibernate advice above)? Or marking it as @TransactionAttribute(TransactionAttributeType.SUPPORTS) doesn't mean much about the database transaction strategy next to the metal?

What I mean, an EJB transaction (JTA) occurs at the application server level. Perhaps it could be (I don't know) that when a Java EE application server interacts with Hibernate, Hibernate will always apply explicit transactions at the database level, regardless of the transaction policy at the application level. Thus, the Hibernate articles I cited here may not apply to JTA transactions at the server application level - perhaps it is good practice to label read-only methods as @TransactionAttribute(TransactionAttribute.SUPPORTS) instead of REQUIRED .

What do people think here? All pointers are welcome - even basic information.

+6
source share
2 answers

If I have an EJB method that performs read-only operations, is it good practice to always state that it is transactional (after the spirit of the Hibernate advice above)?

In my opinion, it depends on the requirements of the use case you are using. If non-repeating reads and / or phantom are read, your read-only method does not have to be executed inside a transaction. For some types of queries or report generation tasks, this is acceptable. On the other hand, think about this situation:

 List<Post> posts = findAllPosts(); for (Post p : posts) { Statistics s = findStatisticByPostId(p.id); doSomethingWithStatistics(s); } 

In this case, one message can return its statistics for the time T1 , and another message for the time T2, where T2 > T1 , since each call to findStatisticByPostId will be executed inside its own transaction, and it is possible that both posts encountered some statistics during (T1...T2) .

So, if you create a report according to the returned Statistics objects, it is impossible to guarantee that the report is based on all the statistics that were available at time point T2 .

Again, depending on the requirements of what you are trying to implement, this is sometimes acceptable, and sometimes not.

+2
source

I see no problems using TransactionAttribute.SUPPORTS, but you need to be sure of the context in which you are working.

What do you actually say: "I don't care about dirty readings." Or phantom reads. The data that you return to the user is not guaranteed in a consistent state, and for many applications this is just fine.

Actually, I believe that as enterprise developers, we tend to abuse transactions. They have significant overhead. And your business example may be tolerant of showing some outdated data in cases where the data being read will never affect the write operation of a line.

In short, I think EJB3 Tx annotations are for a specific purpose. If you understand their semantics and your application correctly, you can make an informed decision about which Tx mode is more appropriate.

S
ALR

+3
source

Source: https://habr.com/ru/post/895430/


All Articles