jdbc中的加锁、处理和释放锁

发布于 2024-12-04 07:49:12 字数 734 浏览 3 评论 0原文

这就是我的要求 - 锁定数据库记录,处理它并释放它

环境 - weblogic 10.3 数据库——Oracle 11g 数据源 - 涉及多个 XA 资源 Tx mgr - JTA

以下是我迄今为止所做的实验结果:

实验 1 - 依靠未提交的读

  1. 读取 db 记录
  2. 通过 id 将记录锁定在另一个表中,作为全局 JTA 的一部分交易
  3. 处理记录 尝试锁定同一记录的第二个事务将失败,并将删除该记录。 但要实现这一点,RDBMS 应该允许脏读。 不幸的是Oracle不支持读未提交隔离级别。

实验2 - 在本地事务中锁定记录

  1. 读取数据库记录
  2. 通过id锁定另一个表中的记录,作为单独的本地事务
  3. 处理记录并在事务提交成功时删除该记录 尝试锁定同一记录的第二个事务将失败,并将删除该记录。这种方法基于提交的数据,应该可以正常工作。 问题是 - 由于锁定事务和全局父事务不同,如果处理失败回滚主事务,我应该通过回滚锁定事务来补偿,我不知道该怎么做 - 需要帮助 。

如果我无法回滚记录锁定事务,则必须在记录锁定代码周围编写一些脏逻辑 我不喜欢这个。

这似乎是一个非常普遍的要求。我想知道你们如何优雅地处理这个问题。 Oracle 是否支持以任何方式使未提交的更新对所有事务可见。

预先非常感谢。

Thats my requirement - to lock a database record, process it and release it

Environment - weblogic 10.3
Database - Oracle 11g
Datasources - multiple XA recources involved
Tx mgr - JTA

Here are the results of the experiments I have done so far:

Experiment 1 - Rely on read uncommitted

  1. Read the db record
  2. Lock the record by id in another table, as part of the global JTA transaction
  3. Process the record
    A second transaction which tries to lock the same record will fail, will drop the record.
    But for this to work the RDBMS should allow dirty reads.
    Unfortunately Oracle does not support read uncommitted isolation level.

Experiment 2 - Lock record in local transaction

  1. Read the db record
  2. Lock the record by id in another table, as a separate local transaction
  3. Process the record and delete the record when the transaction commits successfully
    A second transaction which tries to lock the same record will fail, will drop the record. This approach is based on committed data, should work fine.
    Here is the problem - Since the lock transaction and the global parent are different, if the processing fails rolling back the main transaction, I should compensate by rolling back the lock transaction, which I do not know how to do - Need help here

If Iam not able to rollback the record locking transaction, would have to write some dirty logic around the record locking code. I dont prefer this.

This appears to be a very common requirement. I would like to know how you guys handle this elegantly.
Does Oracle support in any way making uncommitted updates visible to all transactions.

Thanks a lot in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

且行且努力 2024-12-11 07:49:12

我们有一个实用程序类,它大致实现了您在实验 2 中描述的内容:

先决条件:有一个用于锁定的专用表

在锁定阶段,创建一个新连接;对锁表执行 INSERT INTO。

在解锁阶段,无论业务逻辑是否执行,都会执行连接回滚。

它的使用方式类似于 java.util.concurrent.locks.Lock:

Lock lock = new Lock(...);
lock.lock();
try {

    // your business logic
} finally {
   lock.unlock();
}

它适用于 websphere / oracle。

请注意,如果您使用 JPA,则有对实体锁定的内置支持。

We have an utility class that implements roughly what you describe in experiment 2:

Prerequisite: having a dedicated table for the lock

On lock phase, a new connection is created; a INSERT INTO is performed on the lock table.

On unlock phase, a rollback on the connection is performed regardless of the execution of the business logic.

It is used like a java.util.concurrent.locks.Lock:

Lock lock = new Lock(...);
lock.lock();
try {

    // your business logic
} finally {
   lock.unlock();
}

It works on websphere / oracle.

Note that if you use JPA, there is a built-in support for entity locking.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文