Database 处理数据库并发性

Database 处理数据库并发性,database,jakarta-ee,concurrency,sum,Database,Jakarta Ee,Concurrency,Sum,这似乎是一个常见的问题,但我不知道一个直截了当的答案- 环境 Java EE环境(多个JVM) 2阶段提交设置 甲骨文数据库 鉴于 具有“金额”列的DB表 思维方式 如果选择总和(金额),其中…+当前金额插入行 问题 竞争条件-我只想在“提交”时插入行。同时,我不希望其他线程访问我用于求和的数据。我还希望尽可能减少未访问的db数据,以避免占用其他线程 当前解决方案 使用Oracle的SELECT FOR UPDATE机制 有人有其他解决这个问题的方法吗?开箱即用的解决方案也会受到欢迎。对

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

环境
  • Java EE环境(多个JVM)
  • 2阶段提交设置
  • 甲骨文数据库
鉴于 具有“金额”列的DB表

思维方式
如果选择总和(金额),其中…+当前金额<常数==>插入行
问题 竞争条件-我只想在“提交”时插入行。同时,我不希望其他线程访问我用于求和的数据。我还希望尽可能减少未访问的db数据,以避免占用其他线程

当前解决方案 使用Oracle的SELECT FOR UPDATE机制



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

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

插入
当sumamount+?<?然后
输入mytable(id、金额、其他字段)值(myseq.nextval、、)
从mytable中选择sum(amount)sumamount
使用以下参数:

  • 新金额
  • 不变的
  • 新金额
  • 其他字段值

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

JPA作为javaee的一部分提供

通常有悲观锁定和乐观锁定

悲观锁定实际上在读取数据时锁定表行(生成的SQL是
选择更新…
作为当前解决方案),例如

Person-Person=em.find(Person.class、personPK、LockModeType.悲观_-WRITE);
乐观锁定为每个表使用一个版本列:

公共类员工{
@ID-int-ID;
@版本int版本;
...

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

谢谢您的回复。我认为您的第一个建议可能不起作用,因为在执行'when'子句时,SUM语句中使用的记录未锁定,因此不会阻止竞争条件。
if SELECT SUM(AMOUNT) WHERE... + current amount < Const. ==> insert row
insert 
  when sumamount + ? < ? then
     into mytable (id, amount, otherfield) values(myseq.nextval, ?, ?)
  select sum(amount) sumamount from mytable