当前位置: 首页 > 知识库问答 >
问题:

线程安全findOrSave在Spring数据JPA中

微生城
2023-03-14

而不是findOrSave操作的天真实现…

public Foo findOrSaveFoo(Foo foo) {
    return fooRepository
            .findFoo(foo)
            .orElseGet(() -> saveFoo(foo));
}

…它有检查比行为并发问题,我需要这样的东西:

public Foo findOrSaveFoo(Foo foo) {
    try {
        return saveFoo(foo);
    } catch (DataIntegrityViolationException ignore) {
        return fooRepository
                .findFoo(foo)
                .orElseThrow(AssertionError::new);
    }
}

但它会在. findFoo(foo)行导致会话出现问题:

null id in ... entry (don't flush the Session after an exception occurs)
org.hibernate.AssertionFailure: null id in ... entry (don't flush the Session after an exception occurs)

有没有办法避免此异常或任何替代的线程安全实现

共有1个答案

翁和正
2023-03-14

您必须在专用事务中运行此方法,方法是使用@Transactional(传播=REQUIRES_NEW)注释该方法,因为事务期间发生的约束违反异常将导致事务回滚。有些数据库有一种方法可以避免约束冲突错误,而是进行更新或忽略失败,但这需要自定义SQL。您可以尝试我在这里概述的方法:使用attachDirty(saveOrUpdate)实现Hibernate事务和并发

 类似资料:
  • 问题内容: 我正在使用Spring Data(JPA)存储库来处理CRUD样板。 我这样定义我的存储库接口: 然后Spring自动为我生成上述接口的实现。我们得到的是代理,但我相信最终我们可以归结为。 如果 基础目标类是线程安全的, 则 A 是线程安全的。因此,问题是:线程安全吗? 问题答案: 通常,是的。假设是一个托管对象,我们将从Spring的工厂类(如果您使用Spring作为容器)或CDI托

  • 问题内容: 我正在编写一个Servlet,该Servlet通过访问和修改数据库中的某些表来处理每个请求。我希望与数据库的连接是线程安全的。我不想为此使用已经存在的库/框架(spring,hibernate等)。 我知道我可以通过以下方式为此使用java的ThreadLocal: 每次调用时,新连接都会添加到对象中,然后在释放连接时将其删除。 这是这样做的正确方法,还是它本身应该扩展类?还是有一种更

  • 在我的测试用例中,我有一个事务方法,它创建用户,然后在从数据库检索该用户的不同线程中调用异步方法。在下面的代码中,在db中找不到用户,dao返回null。如何确保不同线程的数据都在那里?冲洗似乎没有帮助。我需要手动提交吗?将隔离级别设置为READ_Uncommitted也没有帮助。 交易服务

  • 我可以让多个线程使用相同的HttpComponentSclientTtpRequestFactory静态实例来安全地创建它们各自的ClientTtpRequest吗? 我假设它是线程安全的,只是因为所有createRequest方法实际上执行了一个request对象的新实例化。例如, 但随后它调用了一些其他可能不是线程安全的方法。 事实上,如果你真的知道答案,哪里有手册会告诉我任何东西的线安全在S

  • 问题内容: 我想知道我需要做什么才能访问数据库线程安全。 这是我的Entity类: 这是DbService类: 这是与DbService一起使用的类: 使 add() , delete() , update() 和 getAll() 方法同步是否足够? 是否可以像在源代码中那样创建DbService的多个实例?还是只需要创建一个实例? 也许我应该使用单例设计模式?还是使DbService静态所有方

  • 问题内容: 我一直在花一些时间调试一个导致分段错误的程序。该错误是不确定性和断断续续的,这很烦人。我把范围缩小到了。我怀疑是在两个不同的线程中拆分字符串的调用导致了分段错误。我可以在两个不同的线程中调用吗? 谢谢。 问题答案: 不是可重入的,因此不应在线程化应用程序中使用它,而应使用。