照顾数据库并发

时间:2012-04-11 14:04:26

标签: database java-ee concurrency sum

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

环境

  • Java EE environemnt(几个JVM)
  • 2阶段提交设置
  • Oracle DB

给定

包含“AMOUNT”列的数据库表

逻辑

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

问题

竞争条件 - 我想只在我'提交'时插入行。同时,我不希望没有其他线程访问我用于总结的数据。我还希望尽可能减少未访问的数据库数据,以免留下其他线程。

当前解决方案

使用Oracle的SELECT FOR UPDATE机制


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

2 个答案:

答案 0 :(得分:0)

使用Oracle,您可以使用INSERT WHEN子句(请参阅here)在数据库中一次性执行条件插入(使用直接JDBC):

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

使用参数:

  • 新金额
  • 常数
  • 新金额
  • 其他字段值

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

答案 1 :(得分:0)

JPA作为Java EE的一部分提供locking mechanisms

一般来说,存在悲观和乐观的锁定。

悲观锁定实际上会在读取数据时锁定表格行(结果SQL是SELECT FOR UPDATE ...作为当前解决方案),例如

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

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

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

悲观的方法似乎最适合你的