首页 > 其他分享 >事务的传播行为

事务的传播行为

时间:2023-03-08 12:12:59浏览次数:32  
标签:事务 default Transactional 存在 传播 PROPAGATION 当前 行为

事务的传播行为

如果当前存在一个事务事务的传播行为(Propagation Behavior)表示整个业务处理过程所跨越的业务对象,将以什么样的行为参与事务。即在一个 service 中调用其他的 service ,事务该怎么处理。

7个传播行为

在 spring 中,事务的隔离级别、传播行为、超时时间等都在接口 org.springframework.transaction.TransactionDefinotion 中定义。TransactionDefinotion 提供了以下几种传播行为:

传播行为 作用
PROPAGATION_REQUIRED 当前存在一个事务就加入,否则创建新事务
PROPAGATION_REQUIRES_NEW 不管是否存在,都创建新事务
PROPAGATION_SUPPORTS 存在就加入,否则直接执行方法
PROPAGATION_MANDATORY 强制要求存在一个事务,否则抛异常
PROPAGATION_NOT_SUPPORTED 不支持当前事务,如果存在就挂起
PROPAGATION_NEVER 永远不需要当前存在事务,否则抛异常
PROPAGATION_NESTED 存在就嵌套事务,不存在就新建

详细介绍:

  • PROPAGATION_REQUIRED :如果当前存在一个事务,则加入当前事务。如果不存在任何事务,则创建一个新的事务。

    PROPAGATION_REQUIRED 通常作为默认的事务传播行为

  • PROPAGATION_REQUIRES_NEW :不管当前是否存在事务,都会创建新的事务。如果存在事务,会将当前事务挂起。

    应用场景:某个业务对象所做的事情不想影响到外层事务时。例如,当前业务方法需要向数据库中更新日志信息,但即便这些日志信息更新失败,我们也不想因为改业务方法的事务回滚,而影响到外层事务的提交。

  • PROPAGATION_SUPPORTS :如果当前存在一个事务,则加入当前事务。如果不存在事务,就直接执行。

    对于一些查询方法来说,该传播行为比较适合。例如,A.Service() 会首先更新数据库,然后调用 B.Service() 进行查询,而如果 B.Service() 是 PROPAGATION_SUPPORTS 传播行为,就可以读取到 A.Service() 更新操作之后的最新结果。

  • PROPAGATION_MANDATORY :强制要求当前存在一个事务,如不存在就抛出异常。

    如果某个方法需要事务支持,但自身又不管理事务提交或回滚,就比较适合用这个传播行为。

  • PROPAGATION_NOT_SUPPORTED :不支持当前事务,而是在没有事务的情况下执行。如果当前存在事务,当前事务原则上将被挂起(Suspend)。

  • PROPAGATION_NEVER :永远不需要当前存在事务,如果存在当前事务,则抛出异常。

  • PROPAGATION_NESTED :如果存在当前事务,则在当前事务的一个嵌套事务中执行;如果不存在当前事务,则与 PROPAGATION_REQUIRED 的行为类似,创建新的事务,在新事务中执行。

超时时间和只读

TransactionDefinition 提供了 TIMEOUT_DEFAULT 常量定义,用来指定事务的超时时间。TIMEOUT_DEFAULT 默认值为-1,这会采用当前事务系统默认的超时时间。我们可以通过 TransactionDefinition 的具体实现类提供自定义的事务超时时间。

TransactionDefinition 提供的最后一个重要信息就是将要创建的是否是一个只读(ReadOnly)的事务。如果需要创建一个只读的事务的话,可以通过 TransactionDefinition 的相关实现类进行设置。只读的事务仅仅是给相应的 ResourceManager 提供一种优化的提示,但最终是否提供优化,则由具体的ResourceManager来决定。对于一些查询来说,我们通常会希望它们采用只读事务。

在代码中使用

我们现在都是用基于注解的声明式事务管理,也就是 @Transactional ,先来看看源码:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
    @AliasFor("transactionManager")
    String value() default "";

    @AliasFor("value")
    String transactionManager() default "";

    Propagation propagation() default Propagation.REQUIRED;

    Isolation isolation() default Isolation.DEFAULT;

    int timeout() default -1;

    boolean readOnly() default false;

    Class<? extends Throwable>[] rollbackFor() default {};

    String[] rollbackForClassName() default {};

    Class<? extends Throwable>[] noRollbackFor() default {};

    String[] noRollbackForClassName() default {};
}

可以看出在注解 @Transactional 中定义了默认的 传播行为、事务隔离级别、超时时间、只读标记、回滚设置等属性。

在实际的应用中,大多数情况下使用这些默认属性就可以满足我们的需求。而如果有特殊需要,也可以在注解中设置符合我们需要的属性值,如下列代码:

@Transactional
@Service
public class QuoteService implements IQuoteService{
  
  @Resource
  private JdbcTemplate jdbcTemplate;
  
  @Trangactional(propagationePropagation.SUPPORTS, readOnly=true, timeout=20)
  public Quote getQuate() {
    return (Quote)getJdbcTemplate().queryForObject("SELECT * FROM fx_quote wherequote_id=2", new RowMapper(){
      public Object mapRow(ResultSetrs, int row) throws SQLException {
        Quote quote = new Quotel;
        //...
        return qote;
      }});
   
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, readOnly=true, timeout=20)
  public Quote getQuateByDaterime(Daterime daterime) {
    throw new NotImolementedException();
  }
  //...
}

public void saveQuote(Quote quote){
  // save...
}

如果将 @Transactional 标注为对象级别的话,对象中的方法将“继承”该对象级别上的 @Transactiona 的事务管理元数据信息。

如果某个方法有特殊的事务管理需求,可以在方法级别添加更加详细的 @Transactional 设定,比如getQuote*()方法。通过将相同的事务管理行为提取到对象级别的@Transactional,可以有效地减少标注的数量。

如果是在 springboot 项目中,需要在启动类上加入 @EnableTransactionManagement

@SpringBootApplication
@MapperScan("com.itle.credit.mapper")
@EnableTransactionManagement	//开启事务支持
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

标签:事务,default,Transactional,存在,传播,PROPAGATION,当前,行为
From: https://www.cnblogs.com/luler/p/17191577.html

相关文章

  • 分布式事务-最大努力通知 20230307
              ......
  • 主题挖掘LDA和情感分析图书馆话题知乎用户问答行为数据|附代码数据
    全文链接:http://tecdat.cn/?p=16890最近我们被客户要求撰写关于主题挖掘LDA和情感分析的研究报告,包括一些图形和统计输出。当前是大数据盛行的时代,各种用户信息行为数据......
  • 详解神经网络中反向传播和梯度下降
    摘要:反向传播指的是计算神经网络参数梯度的方法。本文分享自华为云社区《反向传播与梯度下降详解》,作者:嵌入式视觉。一,前向传播与反向传播1.1,神经网络训练过程神经网......
  • 微服务之事务管理Seata
    Seata是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务,也是SpringCloudAlibaba提供的组件, Seata官方文档:为什么需要Sea......
  • 20_Spring_零XML事务控制
    ​ 创建配置类 packagecom.msb.config;importcom.alibaba.druid.pool.DruidDataSource;importorg.springframework.beans.factory.annotation.Value;importor......
  • 20_Spring_零XML事务控制
     创建配置类 packagecom.msb.config;importcom.alibaba.druid.pool.DruidDataSource;importorg.springframework.beans.factory.annotation.Value;importorg.springf......
  • 20_Spring_零XML事务控制
     创建配置类 packagecom.msb.config;importcom.alibaba.druid.pool.DruidDataSource;importorg.springframework.beans.factory.annotation.Value;importorg.springf......
  • 20_Spring_零XML事务控制
    ​ 创建配置类 packagecom.msb.config;importcom.alibaba.druid.pool.DruidDataSource;importorg.springframework.beans.factory.annotation.Value;importor......
  • MySQL事务的隔离级别
    1.读未提交读取到别人未提交的数据,即脏读2.读已提交读取别人已经提交的数据,但是不同时间点读取到的数据可能并不一致,别人可能多次提交了不同的数据,这种即不可重复读3.......
  • 19_Spring_事务管理XML配置方式
    ​ applicationContext中,通过AOP实现事务的控制 <?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xm......