H2数据库释放锁

Posted

技术标签:

【中文标题】H2数据库释放锁【英文标题】:Release lock of H2 database 【发布时间】:2017-08-27 16:04:50 【问题描述】:

我正在尝试在 H2 数据库中使用行级锁定。有没有办法在单个连接中获取和释放记录级锁?

SELECT *
FROM "locks"
WHERE key = 'lock1'
FOR UPDATE;

SELECT *
FROM "locks"
WHERE key = 'lock2'
FOR UPDATE;

现在我想释放lock1,但继续持有lock2。 我试图插入“BEGIN TRANSACTION;”在 lock2 之前,但 COMMIT 释放两个锁。

补充: 我将使用 H2 之类的本地缓存作为服务器数据库。 目标是实现跨程序同步(java)。 数据不会 1:1 同步,程序将控制存储的内容。 FileChannels 在 Linux 中不工作,套接字工作正常,但我发现它们是丑陋的解决方案。 任务:

    数据库与服务器同步;只有一个程序应该执行同步。 日志写入;程序使用 2 个日志文件并从一个切换到另一个。为防止冲突,我们应该锁定文件的写入时间。 可能是别的东西。

此时我看到了两种方式

    每次创建新连接并在任务执行后释放。建立连接需要近 600 毫秒。 使用临时表:CREATE AND DROP TEMPORARY TABLE tmp_lock1()。耗时 2ms。问题:如果有 2 个连接和第一个创建临时表并突然完成工作(例如一些错误),表将仍然存在,直到第二个程序工作。

【问题讨论】:

【参考方案1】:

我自己没试过,理论上应该可以插入记录,选择更新删除解除锁定记录。 H2 不能在 MVCC 模式下使用,否则其他连接将看不到新记录。

我不确定,你想要实现什么,这可能不是要走的路,但应该释放锁而另一个坚持。

【讨论】:

【参考方案2】:

理论上你应该可以像这样使用 SAVEPOINT:

SELECT * FROM "locks" WHERE key = 'lock1' FOR UPDATE;
SAVEPOINT beforeLock2;
SELECT * FROM "locks" WHERE key = 'lock2' FOR UPDATE;
ROLLBACK TO SAVEPOINT beforeLock2;

实际上它不起作用,lock2 行仍然锁定,可能是一个错误,所以我发布它希望 Thomas 能看到它。

根据您的描述,我看不出您无法使用两个连接的任何原因,一个用于lock1,另一个用于lock2。您可以使用连接池,这样创建连接所需的时间就不会成为问题。

【讨论】:

以上是关于H2数据库释放锁的主要内容,如果未能解决你的问题,请参考以下文章

数据库锁表查询及释放锁

数据库 事物 锁

多线程并发编程总结

oracle查看锁和释放锁

redigo 连接池 - 为啥在删除陈旧连接时释放锁

是否可以从活动(大量数据移动)存储过程中释放事务日志锁?