释放SELECT ... FOR UPDATE锁

时间:2018-01-18 09:59:43

标签: sql hibernate

我的问题非常简单:SELECT ID FROM TABLE FOR UPDATE NOWAIT的反向SQL语句是什么?如何在提交之前获取锁定的同一事务中释放锁定?

扩展:我正在编写可移植的API代码,利用Hibernate将行级锁应用于实体。实现者可以使用以下API

@Override
public void lock(T object)
{
    try
    {
        getHibernateTemplate().lock(object, LockMode.UPGRADE_NOWAIT);
    }
    catch (Throwable e)
    {
        log.error(e.getMessage(), e);
        throw e;
    }
}

@Override
public void unlock(T object)
{
    try
    {
        getHibernateTemplate().lock(object, LockMode.NONE);
    }
    catch (Throwable e)
    {
        log.error(e.getMessage(), e);
        throw e;
    }
}

我在交易中使用锁码。 Lock方法可以作为一个魅力,我得到预期的并发异常,我期待它们!我看到,在从持久层获取实体后,Hibernate会执行上面显示的SQL查询来锁定对象。我将unlock方法写成lock方法的自然对偶。

除了提交/滚动事务之外,是否可以自愿释放对象上的锁?或者降级

我已经google了一下但是既没有找到SELECT FOR UPDATE的反向SQL语句,也没有找到Hibernate在降级锁时所做的事情。我怀疑释放锁是主要SQL数据库中实际上不可能的事情,因此任何调用代码都不应使用unlock() API。我负责的项目不要求在事务期间自愿释放锁(他们将在最坏的情况下提交只读事务),但我对自己unlock API的有用性提出质疑。

我愿意省略运行我的应用程序的数据库,因为这是MS Sql,MySql,Postgres和Oracle的可移植API代码

2 个答案:

答案 0 :(得分:1)

在大多数数据库中 - 如果没有COMMIT或ROLLBACK,则无法释放锁。

据我所知,当您选择更新时,数据库(在封面下)会将此视为作为交易一部分发生的更新。因此,就像任何其他更新一样,锁仅在COMMIT或ROLLBACK中释放。想象一下,获取锁的同一事务也对记录进行了更新。在这种情况下,它只是变得太复杂而无法支持显式解锁并检查事务是否在锁定时确实对记录执行了任何其他操作。不同的隔离级别会进一步增加复杂性。

答案 1 :(得分:-1)

MySQL 8.0支持选择更新跳过锁定

请参阅此处:https://dev.mysql.com/doc/refman/8.0/en/select.html