Spring Framework @Transactional Operation

3

1 - Does the Spring documentation describe the use of @Transactional of Spring in business rule classes ( ProdutosService for example) has any special reason to use this annotation in these classes instead of using DAO's?

2 - The operation of the @Transactional annotation is the same as the use of the Open Session in View standard? If not, in which situations is it more interesting to use one instead of the other?

    
asked by anonymous 24.07.2014 / 21:31

1 answer

7

Note @Transactional demarcates transactions (you can start nested transactions, propagate transactions to other layers, etc.). The transaction is an isolated worker drive that takes the database from a consistent state to another consistent state. Think in terms of same business transactions.

The recommendation not to demarcate the DAO layer but rather the business layer is due to the very nature and granularity of each layer's operations. DAO layer operations usually have fine granularity (insert something, update something, see something, etc). However, the business layer is of a thicker granularity, and can cluster several operations of the DAO layer (as well as other layers, eg, 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 what business methods are good candidates for transactional "work units". The idea is that the work unit that takes the bank from one consistent state to another consistent state performs several operations. You want one of two things to happen:

  • The business method runs successfully and a commit of everything is done
  • An 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 noted the DAO2 insertion method with @Transactional(propagation=Propagation.REQUIRES_NEW) (something that made sense in a particular piece of your application). If you do this your business method will no longer rollback than was DAO2 (since insert happens in your own transaction ). Now imagine that update on DAO1 failed and raised an exception; This will make a rollback of this update , but the DAO2 value entered in the previous step will be maintained, potentially leaving your database in a inconsistent state. In this way it is good practice to make the DAO layer a mere "consumer" of transactions, not an active agent of demarcations.

    Open Session in view replaces transactional demarcation?

    No . Okay, I was kind of categorical here; but the truth is that if all the transactions in your application have the same scope of the transaction-per-request, this is a strong indication that something is wrong.

    The purpose of the Open Session in View OSiV ) rule is to make it easier for the programmer to live lazy < in>) at render time of view (avoiding LazyInitializationException and similar).

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

    I've already had several discussions about the OSiV standard, personally I consider it an anti-default, or at least bad practice. While there are several advocates of the standard, I am not alone in the dissenting list . OSiV is certainly useful and saves programmer time by avoiding having to worry about checking if the expected objects were loaded correctly. On the other hand abusing this type of technique also stimulates the proliferation of several problems. Disassociation with transactional demarcation is one of them, as well as problems of type N + 1 queries.

    Let's say, for example, that your JPA provider has to query to retrieve each entity from a lazy list, this will generate a number of 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 the architectural point of view, cross-sectional long sessions end up tying the layers: exceptions from the data layer potentially affect view , which can happen at render time. From the point of view of performance sessions of long duration end up consuming more resources. From a reliability point of view, the standard will make room for unexpected failures, etc., etc., etc.

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

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

        
    25.07.2014 / 00:52