2011-09-12 52 views
0

锁定这就是我的要求 - 锁定数据库记录,处理它,然后松开锁,工艺和释放JDBC

环境 - 的WebLogic 10.3 数据库 - 的Oracle 11g 数据源 - 多XA的recources参与 的Tx经理 - JTA

下面是到目前为止,我已经做了实验结果:

实验1 - 依靠读取未提交

  1. 读取数据库记录
  2. 通过ID锁定记录在另一表中,作为全局JTA事务
  3. 过程记录 它试图锁定同一记录将失败的第二个交易的一部分,将下降记录。 但是为了这个工作,RDBMS应该允许脏读。 不幸的是,Oracle不支持读取未提交的隔离级别。

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

  1. 阅读分贝记录
  2. 另一个表通过ID锁定记录,作为一个独立的本地事务
  3. 过程中的记录和在事务成功提交时删除记录 尝试锁定相同记录的第二个事务将失败,将删除该记录。这种方法基于承诺的数据,应该工作正常。 这里是问题 - 由于锁定事务和全局父项是不同的,如果处理失败回滚主要事务,我应该回滚锁定事务,我不知道该怎么办 - 需要帮助在这里

如果Iam无法回滚记录锁定事务,将不得不围绕记录锁定代码编写一些脏逻辑。我不喜欢这个。

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

非常感谢。

+0

在实验中发生的事情是以下几点:获得数据库记录,锁定由ID记录在另一张表(我假设你插入ID到另一个表,该ID是主键)。这将锁定这条记录。任何其他试图将相同密钥插入表的事务都会阻塞/失败。 – steve

回答

1

我们有一个实现大致是你在实验2描述了一个实用工具类:

先决条件:具有用于锁定

在锁定期专用表,创建一个新的连接;在锁定表上执行INSERT INTO。

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

它被用作一个java.util.concurrent.locks。锁:

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

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

它适用于websphere/oracle。

请注意,如果你使用JPA,有一个内置的实体锁定支持。

+0

这是一个完美的工作示例。这里你的代码控制整个工作流程。但在我们的情况下,这是春季整合框架。消费者的多个实例驻留在不同的weblogic节点中(每个节点1个)。在处理消息之前,我可以将更改提交到临时表。我也可以释放锁定后处理。但是,如果在消息处理中有一个异常,那么锁将会卡住(我在异常情况下没有回调)。所以我应该在消息处理之前根据锁的年龄编写一些脏逻辑。这是我的问题 – Krish

+0

是否有可能管理客户端的锁?如果消费者是MDB,拦截器可以管理锁;它会保持您的业务逻辑清洁。 –

+0

我的目标是保持消息不被传递给1个以上的消费者。如果消费者处理中止作为例外情况是我唯一的出路,这是不优雅的。 – Krish