代码之家  ›  专栏  ›  技术社区  ›  Daniel Taub

如何在postgres-Hibernate中设置锁超时

  •  8
  • Daniel Taub  · 技术社区  · 8 年前

    我想定一个目标 Lock 对于下一次提交之前我正在处理的行:

    entityManager.createQuery("SELECT value from Table where id=:id")
                .setParameter("id", "123")
                .setLockMode(LockModeType.PESSIMISTIC_WRITE)
                .setHint("javax.persistence.lock.timeout", 10000)
                .getSingleResult();
    

    我认为应该发生的是,如果两个线程同时尝试写入db,那么一个线程将在另一个线程之前到达update操作,第二个线程应该等待10秒,然后抛出 PessimisticLockException .

    看看这个例子:

    database.createTransaction(transaction -> {
        // Execute the first request to the db, and lock the table
        requestAndLock(transaction);
    
        // open another transaction, and execute the second request in
        // a different transaction
        database.createTransaction(secondTransaction -> {
            requestAndLock(secondTransaction);
        });
    
        transaction.commit();
    });
    

    我希望在第二个请求中,事务将等待设置的超时,然后抛出 悲观锁异常

    Hibernate通过以下方式生成对db的请求:

    SELECT value from Table where id=123 FOR UPDATE
    

    在这个 answer Postgres 仅允许 SELECT FOR UPDATE NO WAIT 这将超时设置为0,但不可能以这种方式设置超时。

    Hibernate / JPA ? 也许 吧 this way 是怎么推荐的?

    4 回复  |  直到 8 年前
        1
  •  5
  •   Thorben Janssen    8 年前

    Hibernate支持 bunch of query hints

    但在此之前,请注意,Hibernate本身并不处理超时。它只将其发送到数据库,这取决于数据库是否应用了它以及如何应用它。

    javax.persistence.lock.timeout 而不是暗示。举个例子:

    entityManager.createQuery("SELECT value from Table where id=:id")
            .setParameter("id", "123")
            .setLockMode(LockModeType.PESSIMISTIC_WRITE)
            .setHint("javax.persistence.lock.timeout", 10000)
            .getSingleResult();
    
        2
  •  1
  •   kan    8 年前

    我想你可以试试

    SET LOCAL lock_timeout = '10s';
    SELECT ....;
    

    你也可以这样做 NO WAIT

        3
  •  1
  •   LuboÅ¡CZ    7 年前

    postgresql的锁超时提示在postresql9.6上不起作用( .setHint("javax.persistence.lock.timeout", 10000

    我找到的唯一解决方案是取消postgresql.conf中lock\u timeout属性的注释:

    lock_timeout = 10000            # in milliseconds, 0 is disabled
    
        4
  •  0
  •   Laurenz Albe    8 年前

    lock_timeout 参数,它完全符合您的要求。

    你可以把它放进去 postgresql.conf 或与 ALTER ROLE ALTER DATABASE 每个用户或每个数据库。