Spring @Transactional annotation when using try catch block

前端 未结 4 1866
花落未央
花落未央 2020-12-13 13:46

If we catch the exception in method annotated with the @Transactional annotation, will it roll back if any exception occurs?

@Transactional(read         


        
相关标签:
4条回答
  • 2020-12-13 14:26

    You have already mentioned attribute:rollbackFor=Throwable.class in your @Transactional annotation.

    So, for any kind of exception transaction will be rolled back.

    0 讨论(0)
  • 2020-12-13 14:27

    for example

    class A{
    
        @Transactional
        public Result doStuff(){
            Result res = null;
            try {
              // do stuff 
            } catch (Exception e) {
    
            }
            return res ;
        }
    }
    

    If there is an exception in the method doStuff the transaction isn't rolled back.

    To rollback the exception programmatically, we can do something like below.

    declarative approach

    @Transactional(rollbackFor={MyException1.class, MyException2.class, ....})
    public Result doStuff(){
       ...
    }
    

    programmatic rollback you need to call it from TransactionAspectSupport.

    public Result doStuff(){
      try {
        // business logic...
      } catch (Exception ex) {
        // trigger rollback programmatically
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
      }
    }
    
    You are strongly encouraged to use the `declarative approach` to `rollback` if at all possible. 
    `Programmatic rollback` is available should only be used if you absolutely need it.
    
    0 讨论(0)
  • 2020-12-13 14:37

    From spring references documentation

    Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies ( proxy-target-class="true") or the weaving-based aspect ( mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad.

    In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.

    Then with @Transaction the default behavior is that any RuntimeException triggers rollback, and any checked Exception does not. Then your transaction roll back for all RuntimeException an for the checked Exception Throwable

    0 讨论(0)
  • 2020-12-13 14:39

    you would want to read this

    Integrated transaction management. You can wrap your ORM code with a declarative, aspect-oriented programming (AOP) style method interceptor either through the @Transactional annotation or by explicitly configuring the transaction AOP advice in an XML configuration file. In both cases, transaction semantics and exception handling (rollback, and so on) are handled for you. As discussed below, in Resource and transaction management, you can also swap various transaction managers, without affecting your ORM-related code. For example, you can swap between local transactions and JTA, with the same full services (such as declarative transactions) available in both scenarios. Additionally, JDBC-related code can fully integrate transactionally with the code you use to do ORM. This is useful for data access that is not suitable for ORM, such as batch processing and BLOB streaming, which still need to share common transactions with ORM operations.

    0 讨论(0)
提交回复
热议问题