从我推断的内容来看,我似乎试图在我的postgresql数据库中插入一个新行,并使用新的主键组合。然而它抱怨我多次插入相同的键。
证据(来自错误日志):
ERROR com.saxo.read.postgres.RequestLoggingStore - Unable to insert request correctly, uri: /someUrlHere, uuid: a7813f97-7c0d-4739-b20b-a2a6ab2f32a3, at: 1470137399294243
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "requestlogging_pkey"
Detail: Key (id, "timestamp")=(a7813f97-7c0d-4739-b20b-a2a6ab2f32a3, 1470137399294243) already exists.
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2270)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1998)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
....
ERROR com.saxo.read.postgres.RequestLoggingStore - Unable to insert request correctly, uri: /someUrlHere, uuid: 1891dc28-64b8-4a16-8d22-67af6a605aa0, at: 1470137399293662
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "requestlogging_pkey"
Detail: Key (id, "timestamp")=(a7813f97-7c0d-4739-b20b-a2a6ab2f32a3, 1470137399294243) already exists.
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2270)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1998)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
....
正如你所看到的,PQSL抱怨我有一个重复的密钥违规,在它应该认为,如果我已经给它它抱怨的值。
(a7813f97-7c0d-4739-b20b-a2a6ab2f32a3, 1470137399294243)
是重复的密钥。但是,从我在RequestLoggingStore中的错误日志中可以看出,报告的uuid和时间戳与PSQL报告的不同,并且不是重复键。
我立即假设我在代码中犯了一个错误,并且报告的UUID和时间戳不是我插入postgresql数据库的内容。但我不知道下面的代码是如何实现的:
public String put(String uri, String method, String body, String headers, String userId) {
String uuid = null;
long timestamp = stamper.timestamp();
try {
uuid = java.util.UUID.randomUUID().toString();
insertQuery.setString(1, uri);
insertQuery.setString(2, body);
insertQuery.setString(3, method);
insertQuery.setString(4, headers);
insertQuery.setString(5, userId);
insertQuery.setLong(6, timestamp);
insertQuery.setString(7, uuid);
insertQuery.execute();
return uuid;
} catch (Exception e) {
logger.error("Unable to insert request correctly, uri: {}, uuid: {}, at: {}", uri, uuid, timestamp, e);
return null;
}
}
以防您想要查看插入查询:
insertQuery = postgresConnection.prepareStatement("INSERT INTO "+TableName+"( "+listOfArgs+" ) VALUES ( ?, ?, ?, ?, ?, ?, ? );");
UUID应该为null,或者与我的错误记录器报告的值相同,是否正确?
2?
之间怎么会有区别?我犯了错误或者psql的java驱动程序有什么问题吗?
我正在将所有传入的请求记录到我的Web服务/ API。测试时似乎工作正常。在高负荷下是否会变得太紧张?
答案 0 :(得分:2)
由于insertQuery
是一个类字段,因此可以在两个线程中调用方法put
并覆盖相同的唯一SQL字段。因此,执行"相同"尝试记录(insertQuery)。
最好的方法是将所有变量保存在局部变量中,然后尝试使用资源。
(也可以将密钥生成留给数据库,并查询PreparedStatement.getGeneratedKeys()
。)