@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方法始终在新事务中运行,确保其他并发任务所做的任何更改不会干扰其执行:
<code class="java">@Transactional(propagation=Propagation.REQUIRES_NEW) public void provideService() { repo1.retrieveFoo(); repo2.retrieveFoo(); }</code>
测试事务行为
验证对于不同传播级别的行为,可以使用 Java 测试:
<code class="java">@Test public void testProvideService() { TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition()); fooService.provideService(); transactionManager.rollback(status); // Assert repository values are unchanged ... }</code>
使用 REQUIRES_NEW,fooService.provideService() 运行后不会回滚在单独的交易中。使用REQUIRED,一切都会回滚。
以上是何时以及为何应调整 @Transactional 中的默认隔离和传播参数?的详细内容。更多信息请关注PHP中文网其他相关文章!