【问题标题】:Database is not changed immediately after the @Transactional method ends@Transactional 方法结束后数据库不会立即更改
【发布时间】:2023-01-20 04:14:43
【问题描述】:

我有一个带有 PostgreSQL 数据库的 Java、Spring Data 应用程序,并且在我的服务层中有一个与此类似的代码:

public void method1() {
    PersonDto dto = method2();
    method3(dto);
}

@Transactional
public PersonDto method2() {
    Person p1 = personRepository.saveAndFlush(new Person());
    return createPersonDto(p1);
}

@Transactional
public void method3(PersonDto p1) {
    Person p2 = personRepository.findById(p1.getId());
    if (p2 == null) {
        System.out.println("Not in the DB");
    } else {
        System.out.println("In the DB");
    }
}

有时这段代码打印“不在数据库中”,而我期望它总是打印“在数据库中”。我的问题是:

  1. 这个 saveAndFlush 有必要吗?由于我没有在同一笔交易中重复使用该实体,我猜它与保存具有相同的效果,对吗?
  2. 如何保证方法2的修改在方法3调用之前提交?所以它总是打印“在数据库中”?
  3. 我正在将我的实体转换为 DTO 的事实是什么搞砸了?也许如果我传递实体本身它会正常工作?

    我正在考虑仅在 method1 中使用 @Transactional,或者将 method3 中的 @Transactional 替换为 @Transactional(isolation = Isolation.READ_UNCOMMITTED)。 有什么建议吗?

【问题讨论】:

  • 1. 您确定PersonDto中的ID与返回的Person对象中的相同ID对应吗?你确定它不为空吗? 2.你确定你没有从另一个事务方法调用method2,因此事务还没有结束,也许method3()是在第一个事务提交之前从另一个事务调用的?
  • 是的,我敢肯定,在 method3 中检索它之前,我有一个日志。此外,它大部分时间都有效,大约 1% 的时间会失败,通常是在执行速度超快时。关于事务,在 StackTrace 中没有其他带有 @Transactional 注释的方法。谢谢!

标签: java postgresql jpa transactions spring-data


【解决方案1】:

我可以看到您获得所描述结果的几个原因。

一种可能性是 @Transactional 不一定表示“在完全独立的事务中执行此方法”。默认传播是REQUIRED,如果一个事务已经处于活动状态,它将使用一个现有的事务。因此,如果 method2() 在之前打开事务的堆栈中被调用,则在提交原始事务之前,它不会创建新的(因此不会提交新实体)。如果发生这种情况,一种解决方案是将传播更改为REQUIRES_NEW

@Transactional(propagation = REQUIRES_NEW)

另一种可能性(似乎更有可能)是这些方法都在同一个类中。要理解失败的原因,您必须了解 Spring 如何实现对 @Transactional(以及大多数其他行为注释)的处理:使用代理。这意味着只有通过代理的方法调用才能获得事务行为。这是一个对象调用它对另一个对象的引用的典型场景;该引用实际上是对代理的引用,它拦截调用并将行为(在本例中为事务性)包装在调用周围。但是,在同一实例中调用方法时,没有代理在起作用(Spring 不会/不能用对代理的引用替换 this),因此没有事务行为。

有几种方法可以解决这个问题,但首先我会考虑如何重构我的类和方法来避免它。如果这不合理,this SO Q&A 中讨论了 AspectJ、TransactionTemplate 以及其他一些想法。


附录: This question and its answers 还讨论了解决代理问题的选项。

【讨论】:

    猜你喜欢
    • 2022-09-28
    • 2020-03-25
    • 1970-01-01
    • 2021-12-12
    相关资源
    最近更新 更多