SpringBoot transaction annotation @Transactional

Original text: https://blog.csdn.net/wkl305268748/article/details/77619367

SpringBoot provides very convenient transaction operations. Transaction rollback can be achieved through annotations, which is very convenient and fast. Let's talk about how to perform transaction operations.

1. Transaction Description

In Spring, there are two ways to implement transactions, namely programmatic transaction management and declarative transaction management. 
Programmatic transaction management:  Programmatic transaction management uses TransactionTemplate or directly uses the underlying PlatformTransactionManager. For programmatic transaction management, Spring recommends using TransactionTemplate. 
Declarative Transaction Management:  Built on top of AOP. Its essence is to intercept the method before and after, and then create or join a transaction before the target method starts, and commit or roll back the transaction according to the execution status after the target method is executed. 
Declarative transaction management does not require intrusion code, and transaction operations can be performed through @Transactional, which is faster and simpler. Recommended Use

2. How to use

Using transactions in Mybatis is very simple, just add the annotation @Transactional to the function without any configuration. Let's take a look at the example of adding a transaction to the controller layer:


@Autowired
OrderServiceorderService;   //order操作的Service层

@ApiOperation(value = "增加OrderCustomer")
@RequestMapping(value = "", method = RequestMethod.POST)
@ResponseBody
@Transactional
public JsonBean<Order> insertOrder(@RequestParam(value = "order") String order) {
    try {
        //创建订单
        Order order = orderService.insert(user.getId(),is_company,fk_want_company_id);
        return new JsonBean(SUCCESS, orderCustomer);
    } 
    catch (ErrorCodeException e)
    {
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        return new JsonBean(e.getErrorCode());
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

@Transactional can act on interfaces, interface methods, classes, and class methods. When used on a class, all public methods of the class will have transaction attributes of that type, and we can also use this annotation at the method level to override the class-level definition. Therefore, it can be used in the Service layer and the Controller layer. The above example is implemented in the Controller layer. We simulate an interface for order submission. JsonBean is the base class for uniformly returning error codes, and ErrorCodeException is a custom exception.

  1. Through @Transactional, transaction operations are implemented.
  2. Spring's AOP, or declarative transaction management, defaults to rollback for unchecked exceptions. That is to say, by default, the RuntimeException() exception or its subclasses are rolled back; checked exceptions, that is, Exceptions that can be caught by try{} will not be rolled back, so for our custom exceptions, set them through rollbackFor, and follow-up will be separately speak
  3. If we need to roll back at the same time after catching the exception, manually roll back through TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();.
  4. Use Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint(); 
    to set the rollback point, and use TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint); to roll back to savePoint.

3. Regular placement

parameter name Function description
readOnly This property is used to set whether the current transaction is a read-only transaction. When set to true, it means read-only, and false means that it can be read and written. The default value is false. For example: @Transactional(readOnly=true)
rollbackFor This property is used to set the exception class array that needs to be rolled back. When the exception in the specified exception array is thrown in the method, the transaction will be rolled back. For example: specify a single exception class: @Transactional(rollbackFor=RuntimeException.class) Specify multiple exception classes: @Transactional(rollbackFor={RuntimeException.class, Exception.class})
rollbackForClassName This property is used to set an array of exception class names that need to be rolled back. When an exception in the specified exception name array is thrown in the method, the transaction will be rolled back. For example: specify a single exception class name @Transactional(rollbackForClassName=”RuntimeException”) Specify multiple exception class names: @Transactional(rollbackForClassName={“RuntimeException”,”Exception”})
noRollbackFor This property is used to set the exception class array that does not need to be rolled back. When the exception in the specified exception array is thrown in the method, the transaction will not be rolled back. For example: Specify a single exception class: @Transactional(noRollbackFor=RuntimeException.class) Specify multiple exception classes: @Transactional(noRollbackFor={RuntimeException.class, Exception.class})
noRollbackForClassName This property is used to set an array of exception class names that do not need to be rolled back. When an exception in the specified exception name array is thrown in the method, the transaction will not be rolled back. For example: Specify a single exception class name: @Transactional(noRollbackForClassName=”RuntimeException”) Specify multiple exception class names: @Transactional(noRollbackForClassName={“RuntimeException”,”Exception”})
propagation 该属性用于设置事务的传播行为。例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
isolation 该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置
timeout 该属性用于设置事务的超时秒数,默认值为-1表示永不超时

4. 事务属性

事务隔离级别 
隔离级别是指若干个并发的事务之间的隔离程度。TransactionDefinition 接口中定义了五个表示隔离级别的常量:

TransactionDefinition.ISOLATION_DEFAULT:这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是TransactionDefinition.ISOLATION_READ_COMMITTED。 
TransactionDefinition.ISOLATION_READ_UNCOMMITTED:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读,不可重复读和幻读,因此很少使用该隔离级别。比如PostgreSQL实际上并没有此级别。 
TransactionDefinition.ISOLATION_READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。 
TransactionDefinition.ISOLATION_REPEATABLE_READ:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。该级别可以防止脏读和不可重复读。 
TransactionDefinition.ISOLATION_SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

事务传播行为 
所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:

TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。 
TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。 
TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。 
TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。 
TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。 
TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

事务超时 
所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。 
默认设置为底层事务系统的超时值,如果底层数据库事务系统没有设置超时值,那么就是none,没有超时限制。

事务只读属性 
只读事务用于客户代码只读但不修改数据的情形,只读事务用于特定情景下的优化,比如使用Hibernate的时候。 
默认为读写事务。


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325881485&siteId=291194637