@Transactional中的隔离和传播参数
在Spring的@Transactional注解中,两个关键参数定义了数据库事务的行为:隔离和传播。本文探讨了何时以及为何应考虑调整其默认值。
传播
传播定义了事务如何相互关联。常见选项包括:
默认值: 必需
隔离
隔离性定义了事务之间的数据契约。它通过指定其他事务所做的数据更改的可见性级别来防止某些数据不一致。主要隔离级别为:
默认值: 因数据库而异(例如,MariaDB 的 REPEATABLE_READ)
实际示例
考虑脏读问题,其中一个事务可以读取另一个事务所做的未提交的更改。
Thread 1 Thread 2 | | Write(x) | | | | Read(x) | | Rollback | | | Value (x) is now dirty (incorrect)
在这种情况下,为了防止脏读,您可以将隔离级别设置为 READ_COMMITTED 并将传播级别设置为 REQUIRED。这种组合确保事务只读取其他事务已提交的数据。
自定义事务
在以下示例中,provideService方法始终在新事务中运行,确保其他并发任务所做的任何更改不会干扰其执行:
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void provideService() {
repo1.retrieveFoo();
repo2.retrieveFoo();
}
测试事务行为
要验证不同传播级别的行为,可以使用 Java 测试:
@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,一切都会回滚。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3