1

似乎是一个常见问题,但我不知道一个直接的答案-

环境

  • Java EE 环境(多个 JVM)
  • 2阶段提交设置
  • 甲骨文数据库

给定

带有“AMOUNT”列的数据库表

逻辑

if SELECT SUM(AMOUNT) WHERE... + current amount < Const. ==> insert row

问题

竞争条件 - 我只想在“提交”时插入行。同时,我不希望其他线程访问我用于求和的数据。我还想尽可能减少未访问的数据库数据,以免滞留其他线程。

当前解决方案

使用 Oracle 的 SELECT FOR UPDATE 机制


有没有人有其他解决方案来处理这个问题?开箱即用的解决方案也将受到欢迎。

4

2 回答 2

0

使用 Oracle,您可以使用该INSERT WHEN子句(请参阅此处)在数据库上一举进行条件插入(使用直接 JDBC):

insert 
  when sumamount + ? < ? then
     into mytable (id, amount, otherfield) values(myseq.nextval, ?, ?)
  select sum(amount) sumamount from mytable

使用参数:

  • 新金额
  • 持续的
  • 新金额
  • 其他字段值

如果这对您不起作用,那么我将使用具有“可序列化”隔离级别的事务管理器来防止脏读、幻读或不可重复读取。

于 2012-04-16T09:40:34.057 回答
0

JPA 作为 Java EE 的一部分提供了锁定机制

一般有悲观锁和乐观锁之分。

悲观锁定实际上会在读取数据时锁定表行(生成的 SQL 是SELECT FOR UPDATE ...您当前的解决方案),例如

Person person = em.find(Person.class, personPK, LockModeType.PESSIMISTIC_WRITE);

乐观锁定为每个表使用一个版本列:

public class Employee {
@ID int id;
@Version int version;
...

悲观的方法似乎最适合你

于 2012-04-16T09:41:26.303 回答