释放 SELECT...FOR UPDATE 锁

usr*_*ΛΩΝ 7 sql hibernate

我的问题很简单:逆向SQL语句是什么SELECT ID FROM TABLE FOR UPDATE NOWAIT?如何在提交前获取锁的同一事务期间释放锁?

扩展:我正在编写可移植的 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我在交易中使用锁定代码。锁定方法就像一个魅力,我在我期望的地方得到了预期的并发异常!我看到,在从持久层获取实体后,Hibernate 会执行上面所示的 SQL 查询来锁定该对象。我将该unlock方法写为自然对偶lock方法。

除了提交/回滚事务之外,是否可以自愿释放对象上持有的锁?还是降级呢

我用谷歌搜索了一下,但既找不到什么是反向 SQL 语句SELECT FOR UPDATE,也找不到 Hibernate 在降级锁时做了什么。我怀疑在主要的 SQL 数据库中释放锁实际上是不可能的,因此unlock()任何调用代码都不应该使用该 API。我负责的项目不需要在事务期间自愿释放锁(最坏的情况下他们会提交只读事务),但我对 API 的有用性产生了疑问unlock

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

Ash*_*h A 6

在大多数数据库中 - 如果没有 COMMIT 或 ROLLBACK 就不可能释放锁。

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