gpt4 book ai didi

multithreading - 处理长时间运行的 Hibernate 事务中的死锁

转载 作者:行者123 更新时间:2023-12-04 06:53:55 24 4
gpt4 key购买 nike

我有一个 Hibernate 应用程序,它可能会对具有相同主键的记录产生并发插入和更新(通过 Session.saveOrUpdate ),该主键已分配。这些事务的运行时间有些长,平均可能为 15 秒(因为数据是从远程源收集的,并在数据传入时持久保存)。我的数据库隔离级别设置为已提交读,并且我使用的是 MySQL 和 InnoDB。

问题是这种情况会产生过多的锁等待,超时,要么是死锁,要么是长事务。这让我有几个问题:

  • 数据库引擎是否只在事务提交时释放其锁?
  • 如果是这种情况,我是否应该寻求缩短交易时间?
  • 如果是这样,使用单独的读取和写入事务是否是一个好习惯,其中写入事务可以缩短并且仅在我的所有数据收集后才发生(我的大部分事务长度涉及收集远程数据)。

  • 编辑:

    这是一个简单的测试,它近似于我认为正在发生的事情。由于我正在处理长时间运行的事务,因此在第一次刷新后很久才会进行提交。因此,为了说明我的情况,我将提交排除在测试之外:
    @Entity
    static class Person {
    @Id
    Long id = Long.valueOf(1);
    @Version
    private int version;
    }

    @Test
    public void updateTest() {
    for (int i = 0; i < 5; i++) {
    new Thread() {
    public void run() {
    Session s = sf.openSession();
    Transaction t = s.beginTransaction();
    Person p = new Person();
    s.saveOrUpdate(p);
    s.flush(); // Waits...
    }
    }.run();
    }
    }

    以及预期产生的查询,等待第二次插入:
    select id, version from person where id=?
    insert into person (version, id) values (?, ?)
    select id, version from person where id=?
    insert into person (version, id) values (?, ?)

    最佳答案

    没错,数据库只有在事务提交时才释放锁。由于您使用的是 hibernate 状态,因此您可以使用乐观锁定,它会长时间锁定数据库。本质上,hibernate 会按照您的建议执行,将读取和写入部分分离为单独的事务。在写入时,它会检查内存中的数据是否在数据库中没有同时更改。

  • Hibernate Reference - Optimistic Transactions
  • 关于multithreading - 处理长时间运行的 Hibernate 事务中的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5096744/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com