@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:我们希望所有的东西都回滚,并保持原样。

你可能感兴趣的:(@Transactional注释中的isolation和 propagation参数分别代表着什么?)