Spring: @Transactional中的propagation属性

在Spring的事务管理中,我们可以使用@Transactional这一annotation来对事务进行声明式的设定。具体而言,就是在类或者方法前添加@Transactional并传入属性参数以获取所需要的Transaction特性。Spring中的@Transactional有5个属性:Propagation、Isolation、Rollback Rules、Timeout和Read-Only,其中Propagation属性定义了Transaction的边界 — 是否使用Transaction、在Transaction已存在的情况下如何表现等。

Propagation属性

@Transactional中Propagation属性有7个选项可供选择:

  • Propagation.MANDATORY。当前方法必须在已经定义的Transaction中运行,如果没有已定义的Transaction则抛出异常。
  • Propagation.NESTED。如果没有已定义的Transaction,当前方法新开一个Transaction并在该Transaction中运行。如果存在已定义的Transaction,当前方法在嵌套事务(Nested Transaction)中运行 — 嵌套事务中可以定义储存点,因此可以独立于外部的Transaction而进行rollback。
  • Propagation.NEVER。当前方法不应在Transaction中运行,如果存在已经定义的Transaction则抛出异常。
  • Propagation.NOT_SUPPORTED。当前方法不应在Transaction中运行,如果存在已经定义的Transaction,则该Transaction暂停(挂起)直至该方法运行完毕。
  • Propagation.REQUIRED。默认值。当前方法必须在Transaction中运行。如果存在已经定义的Transaction,则该方法在已定义的Transaction中运行;如果不存在已经定义的Transaction,则该方法新开一个Transaction并在其中运行。
  • Propagation.REQUIRES_NEW。当前方法必须在新开的Transaction中运行。如果存在已经定义的Transaction,则该已定义的Transaction暂停直至新开的Transaction执行完毕。
  • Propagation.SUPPORTS。当前方法不需要在Transaction中运行,但如果存在已经定义的Transaction,则该方法也可以在Transaction中正常执行。

Propagation属性实例

观察以下两个定义了@Transactional的方法,innerMethod()模拟了Transaction已经存在的情况,outMethod()则模拟了不存在已定义Transaction的情况:

@Transactional
public void outMethod() {  
    exampleDAO.doSomething();
    innerMethod();
}

@Transactional
public void innerMethod() {  
    exampleDAO.doElse();
}

对于这两个方法,定义不同的Propagation属性值所产生的效果如下(Propagation.NESTED的情况较为复杂,在此忽略):

Propagation属性 outMethod innerMethod
Propagation.MANDATORY 抛出异常 在outMethod的Transaction中运行
Propagation.NEVER 不在Transaction中运行 抛出异常
Propagation.NOT_SUPPORTED 不在Transaction中运行 outMethod的Transaction暂停直至innerMethod执行完毕
Propagation.REQUIRED (默认值) 新开一个Transaction并在其中运行 在outMethod的Transaction中运行
Propagation.REQUIRES_NEW 新开一个Transaction并在其中运行 outMethod的Transaction暂停直至innerMethod中新开的Transaction执行完毕
Propagation.SUPPORTS 不在Transaction中运行 在outMethod的Transaction中运行

Chuan Shao

Read more posts by this author.

Shanghai

Subscribe to Chuan's blog

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!