加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

多线程 – 处理长时间运行的Hibernate事务中的死锁

发布时间:2020-12-15 02:23:56 所属栏目:Java 来源:网络整理
导读:我有一个Hibernate应用程序可以产生并发插入和更新(通过Session.saveOrUpdate)到具有相同主键的记录,该主键被分配.这些事务有点长时间运行,平均可能是15秒(因为数据是从远程数据源收集的,并且在它进入时会持续存在).我的数据库隔离级别设置为Read Committed,
我有一个Hibernate应用程序可以产生并发插入和更新(通过Session.saveOrUpdate)到具有相同主键的记录,该主键被分配.这些事务有点长时间运行,平均可能是15秒(因为数据是从远程数据源收集的,并且在它进入时会持续存在).我的数据库隔离级别设置为Read Committed,我正在使用 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,?)

解决方法

这是正确的,数据库仅在提交事务时才释放锁.由于您正在使用hibernate,因此可以使用乐观锁定,这会锁定数据库很长一段时间.从本质上讲,hibernate完成了你的建议,将读写部分分成单独的事务.在写入时,它检查内存中的数据是否未在数据库中同时更改.

> Hibernate Reference – Optimistic Transactions

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读