@Transactional注释中的isolation和 propagation参数分别代表着什么?

转载:https://cloud.tencent.com/developer/ask/78013

propagation

事务之间应如何相互关联

  • Required:代码将始终在事务中运行。创建一个新事务,或者在可用的情况下重用一个事务。
  • Requires_new:代码将始终在新事务中运行。如果存在当前事务,则暂停当前事务。

isolation

定义事务之间的数据契约。

  • Read Uncommitted*允许脏读
  • Read Committed*不允许脏读
  • Repeatable Read*如果一行在相同的传输中被读取两次,则结果总是相同的。
  • Serializable:按顺序执行所有事务

在多线程应用程序中,不同级别具有不同的性能特征,并且你还需要了解dirty reads概念。

以下示例可能会发生脏读。

  thread 1   thread 2      
      |         |
    write(x)    |
      |         |
      |        read(x)
      |         |
    rollback    |
      v         v 
           value (x) is now dirty (incorrect)

因此,一个正常的默认值(如果可以声明的话)可以为Read Comitted,它只允许你读取已经由其他运行事务处理的值,并且可以结合Required的传播级别。如果你的应用程序有需求的话,在这里同样也能起作用。

当进入provideService时将始终创建新事务,并在离开时完成。

public class FooService {
    private Repository repo1;
    private Repository repo2;

    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void provideService() {
        repo1.retrieveFoo();
        repo2.retrieveFoo();
    }
}

如果我们使用了Required,那么当事务在进入程序时并且已经打开的时候,事务将保持打开状态。还要注意rollback的结果可能不同,因为多个执行可以参与相同的事务。

我们可以对行为进行测试,并查看结果与传播级别的差异。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:/fooService.xml")
public class FooServiceTests {

    private @Autowired TransactionManager transactionManager;
    private @Autowired FooService fooService;

    @Test
    public void testProvideService() {
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        fooService.provideService();
        transactionManager.rollback(status);
        // assert repository values are unchanged ... 
}

传播水平为

  • Requires new:由于它已经创建了自己的子事务,我们希望fooService.provideService()没有回滚。
  • Required:我们希望所有的东西都回滚,并保持原样。
posted @ 2020-07-09 23:13  soraya  阅读(799)  评论(0编辑  收藏  举报