gpt4 book ai didi

java - Spring @Transactional - 隔离、传播

转载 作者:bug小助手 更新时间:2023-10-28 10:36:05 25 4
gpt4 key购买 nike

有人可以通过真实示例解释 @Transactional 注释中的 isolationpropagation 参数是什么吗?

基本上什么时候以及为什么我应该选择更改它们的默认值。

最佳答案

好问题,虽然不是一个容易回答的问题。

Propagation

定义事务如何相互关联。常用选项:

  • REQUIRED:代码将始终在事务中运行。创建一个新事务或重复使用一个(如果有)。
  • REQUIRES_NEW:代码将始终在新事务中运行。如果存在,则暂停当前事务。

@Transactional 的默认值是 REQUIRED,这通常是您想要的。

Isolation

定义交易之间的数据契约。

  • ISOLATION_READ_UNCOMMITTED:允许脏读。
  • ISOLATION_READ_COMMITTED:不允许脏读。
  • ISOLATION_REPEATABLE_READ:如果一行在同一个事务中被读取两次,结果总是一样的。
  • ISOLATION_SERIALIZABLE:按顺序执行所有事务。

在多线程应用程序中,不同的级别具有不同的性能特征。我认为如果您了解 脏读 概念,您将能够选择一个好的选项。

默认值可能因不同的数据库而异。例如,对于 MariaDB它是可重复阅读


可能发生脏读的示例:

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

所以一个合理的默认值(如果可以声明的话)可以是 ISOLATION_READ_COMMITTED,它只允许您读取已经被其他正在运行的事务提交的值,结合传播级别 必需的。然后,如果您的应用程序有其他需求,您可以从那里开始工作。


一个实际示例,说明在进入 provideService 例程时始终会创建新事务并在离开时完成:

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

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

如果我们改为使用 REQUIRED,事务 would remain open如果在进入例程时事务已经打开。另请注意,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:我们希望一切都回滚并且后备存储没有改变。

关于java - Spring @Transactional - 隔离、传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8490852/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com