2017-08-27 348 views
0

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

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

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

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

此外: 我打算使用H2像本地缓存服务器数据库。 目标是实现交叉程序同步(java)。 数据将不会以1:1同步,程序将控制要存储的内容。 FileChannels在Linux中不起作用,套接字工作正常,但我发现它们很难看。 任务:

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

在这一刻,我看到两种方式

  1. 创建新的连接每个时间和任务执行后释放。连接建立需要近600ms。
  2. 使用临时表:CREATE AND DROP TEMPORARY TABLE tmp_lock1()。需要2ms。问题:如果有2个连接并且第一次创建临时表并突然完成工作(例如某个错误),则在第二个程序工作之前,表仍然存在。

回答

0

我从来没有尝试过自己,理论上你应该能够插入记录,选择它来进行更新删除记录解除锁定。 H2不能在MVCC中使用 - 否则新记录不会被另一个连接看到。

我不确定,你想达到什么目的,这可能不是要走的路,但锁应该被释放,其他人仍然存在。

0

从理论上讲,你应该能够使用SAVEPOINT像这样:

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

在实践中它不工作和lock2行保持锁定状态,可能是这样,我张贴在希望托马斯的错误会看到它。

从你所描述的我看不出有什么理由为什么你将无法使用2个连接之一为lock1和另一个为lock2。您可以使用连接池,然后创建连接所需的时间不会成为问题。