首页  >  文章  >  Java  >  何时以及为何应调整 @Transactional 中的默认隔离和传播参数?

何时以及为何应调整 @Transactional 中的默认隔离和传播参数?

DDD
DDD原创
2024-11-03 19:56:02627浏览

When and Why Should You Adjust the Default Isolation and Propagation Parameters in @Transactional?

@Transactional 中的隔离和传播参数

在 Spring 的 @Transactional 注解中,两个关键参数定义了数据库事务的行为:隔离和传播。本文探讨了何时以及为何应考虑调整其默认值。

传播

传播定义事务如何相互关联。常见选项包括:

  • REQUIRED: 在现有事务中运行代码,如果不存在则创建一个新事务。
  • REQUIRES_NEW: 始终创建新交易,暂停任何现有交易。

默认值: 必需

隔离

隔离性定义了事务之间的数据契约。它通过指定其他事务所做的数据更改的可见性级别来防止某些数据不一致。关键隔离级别为:

  • READ_UNCOMMITTED: 无脏读保护。
  • SERIALIZABLE: 最强隔离,确保无数据冲突。

默认值: 因数据库而异(例如,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_NEWfooService.provideService() 运行后不会回滚在单独的交易中。使用REQUIRED,一切都会回滚。

以上是何时以及为何应调整 @Transactional 中的默认隔离和传播参数?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn