gpt4 book ai didi

java - 并发进程向数据库中插入数据

转载 作者:行者123 更新时间:2023-11-29 13:07:37 26 4
gpt4 key购买 nike

考虑 postgres 数据库中的以下模式。

CREATE TABLE employee
(
id_employee serial NOT NULL PrimarKey,
tx_email_address text NOT NULL Unique,
tx_passwd character varying(256)
)

我有一个 java 类执行以下操作

conn.setAutoComit(false);

ResultSet rs = stmt.("select * from employee where tx_email_address = 'test1'");
if (!rs.next()) {
Insert Into employee Values ('test1', 'test1');
}
ResultSet rs = stmt.("select * from employee where tx_email_address = 'test2'");
if (!rs.next()) {
Insert Into employee Values ('test2', 'test2');
}
ResultSet rs = stmt.("select * from employee where tx_email_address = 'test3'");
if (!rs.next()) {
Insert Into employee Values ('test3', 'test3');
}
ResultSet rs = stmt.("select * from employee where tx_email_address = 'test4'");
if (!rs.next()) {
Insert Into employee Values ('test4', 'test4');
}

conn.commit();
conn.setAutoComit(true);

这里的问题是,如果上面提到的事务有两个或多个并发实例试图写入数据。只有一个事务最终会成功,其余事务将抛出 SQLException“违反唯一键约束”。我们如何解决这个问题。

PS:我只选择了一个表和简单的插入查询来演示问题。我的应用程序是基于 java 的应用程序,其唯一目的是将数据写入目标数据库。并且可能有并发进程这样做,并且某些进程可能试图写入相同数据的可能性非常高(如上例所示)。

最佳答案

最简单的方法似乎是使用事务隔离级别“可序列化”,它可以防止幻读(其他人插入满足您事务期间先前 SELECT 的数据)。

if (!conn.getMetaData().supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE)) {
// OK, you're hosed. Hope for your sake your drivers supports this isolation level
}
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);

还有诸如 Oracle 的“MERGE”语句之类的技术——根据数据是否存在,执行“插入或更新”的单个语句。我不知道 Postgres 是否有等价物,但有一些技术可以“伪造”它——参见例如How to write INSERT IF NOT EXISTS queries in standard SQL .

关于java - 并发进程向数据库中插入数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1125117/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com