重复插入

时间:2012-07-13 22:45:01

标签: java sql transactions transactionscope

在并发请求的情况下,我遇到了重复插入的问题。

我有两张桌子:

create table tbl (
  val varchar2(1000)
);

create table tbl2 (
  val varchar2(1000)
);

我需要在表tbl2中插入一些值,以防表tbl为空。因此,在我的Java代码中,我在事务中使用隔离级别= READ COMMITED:

//start transaction
int result = jdbcTemplate.queryForInt("select count(*) from tbl");
if (result == 0) {
  int update = jdbcTemplate.update("insert into tbl2(val) values(?)", "di" + UUID.randomUUID().toString());
}
//end transaction

这里的问题是:有人实际上可以在if (result == 0)和我的更新语句之间插入数据。所以我会有重复的条目。

我的例子过于简单了,但我的实际情况要复杂得多,但基本思路是一样的:我需要在插入之前从Javacode中做出几个选择。

那么,如何避免这种情况(我对数据库端解决方案和java端解决方案感兴趣)?

P.S。数据库是Oracle。

2 个答案:

答案 0 :(得分:1)

不太确定你为什么要做你正在做的事情,但你可以先锁定表。

LOCK TABLE tbl IN SHARE MODE;

记得COMMIT;释放锁。

答案 1 :(得分:1)

我认为处理这种情况的最佳方法可能是数据库级别。您可以使用如下查询:

insert into tbl2 values(xx) where not exists (select 1 from tbl1)

所以你的查询可能会变成这样的

int update = jdbcTemplate.update("insert into tbl2(val) values(?) where not exists (select 1 from tbl1)", "di" + UUID.randomUUID().toString());