How Spring framework @Transactional works

1-The Spring documentation describes the use of spring @Transactional in business rule classes(ProdutosService for example) do you have any special reason to use this annotation in these classes instead of using DAO's?

2 - the operation of the annotation @Transactional and the same as the use of the default Open Session in View ? Otherwise, in which situations is it more interesting to use one rather than the other?

Author: Maniero, 2014-07-24

1 answers

The @Transactional annotation demarcates transactions (you can initiate nested transactions, propagate transactions to other layers, etc.). The transaction is an isolated unit of work that takes the database from one consistent state to another consistent state. Think in terms of even business transactions.

The recommendation for not demarcating the DAO layer but rather the business layer is due to the very nature and granularity of operations of each layer. Dao layer operations generally they have fine granularity(insert something, update something, refer to something, etc). The business layer is thicker granularity, and can group multiple operations from the DAO layer (as well as from other layers; e.g., JMS queues).

Bean de Negócio
  @Autowired BeanDAO1
  @Autowired BeanDAO2

  @Transactional  
  meu método de negócio() {
     consulta algo do DAO1
     faz um processamento
     insere algo no DAO2
     faz um update no DAO1
  }

See which business methods are good candidates for transactional" work units". The idea is that the unit of work that takes the bank from one consistent state to another consistent state performs several operations. You want one of two things occur:

  1. the business method is executed successfully and a commit of everything is done
  2. any exception should occur, in which case a rollback should be made to the previous state (as if none of the operations had occurred).

Now imagine that you annotated the method of inserting the DAO2 with @Transactional(propagation=Propagation.REQUIRES_NEW) (something that made sense in a certain piece of your application). If you do this your business method will not more do rollback than was inserted in DAO2 (since insert happens in its own transaction). Now Imagine that in the update on DAO1 failed, and he sent out an exception to this will be lot that update, but the value that is entered for the DAO2 in the previous step, it will be upheld, potentially leaving your database in an inconsistent state. In this way it is good practice to make the layer of DAO is a mere "consumer" of transactions, and not an active agent of demarcations.


Open Session in view replaces transactional demarcation?

Not . Ok, I was somewhat categorical here; but the truth is that if all the transactions in your application have the same scope of the request (transaction-per-request) this is a strong indication that there is something wrong.

The purpose of the pattern Open Session in View (OSiV ) is to make life easier for the programmer by allowing entities to be loaded lazily ( lazy ) at render time of the view (avoiding LazyInitializationException and the like).

<!-- Poderia disparar uma exceção se a sessão estivesse fechada -->  
#{minhaEntidade.listaDeOutrasEntidadesLazy}  

I have had several discussions about the standard OSiV, personally I consider it an anti-standard, or at least a bad practice. While there are several proponents of the pattern, I am not alone on the list of dissenters . OSiV is certainly useful and saves the programmer time by preventing him from having to worry about checking if the expected objects have been correctly loaded. On the other hand abusing this type of technique also stimulates the proliferation of various problems. Disregard with transactional demarcation is one of them, as well as problems of type N + 1queries.

Say for example that your JPA provider has to make a query to retrieve each of the entities from a list lazy , this will generate several unnecessary selects; something that could have been easily solved with a JOIN FETCH will potentially go undetected for production due to the use of OSiV. In the best case OSiV acts as a safety net and hides the problem, in the worst case it creates an even bigger problem.

From an architectural point of view long cross sessions end up tying the layers: exceptions to the data layer potentially affect the view, which can happen at render time. From the point of view of performance long sessions end up consuming more resources. From the point of view of reliability the standard ends up making room for unexpected failures, etc, etc, etc.

Anyway, as the subject is controversial, I make it clear that this is only my opinion.

Now about transactional control there is not much to be discussed; your business methods should have well-demarcated transactions according to the rules of its application. If eventually you want to use OSiV to load something into view ok, but at this stage all business transactions must have already been committed. That is, it is one thing for business transactions with potentially destructive write operations and quite another is the session that stays open in the view for the purpose of late loading objects of a given query.

 13
Author: Anthony Accioly, 2017-02-10 17:31:55