Java JDBC主键Oracle数据库

时间:2014-06-10 08:26:12

标签: java oracle jdbc concurrency

我正在使用Java开发应用程序,我有一个Oracle数据库。要存储数据我正在使用JDBC。在Oracle数据库中,没有像自动增量那样的东西。所以我使用触发器来获得最新的主键。

目前应用程序已经实现,我将保存的主键恢复。设置connection.setAutoCommit(true)时会发生这种情况。如果我设置了connection.setAutoCommit(false),我想知道是否有可能获得主键?

我之所以这样问是因为我遇到了多个线程的并发问题,其中一个线程保存数据,另一个线程可以获取保存的记录。我不希望这种情况发生。我希望在另一个线程查看数据之前顺序完成代码。所以,我试图调查JDBC行锁定,但不存在这样的情况。

这个主键是在同一个Thread中输入另一个方法所必需的。

2 个答案:

答案 0 :(得分:1)

检索主键的正确方法是使用getGeneratedKeys工具(可以使用Statement.RETURN_GENERATED_KEYSStatement.execute*之一使用Connection.prepareStatement值激活该工具方法

在大多数数据库中,这可以用于直接检索主键。但是对于Oracle,这将允许您获取ROWID,此ROWID可用于查询表中插入的行并获取主键。

例如:

stmt.executeUpdate("INSERT INTO theTable(column1) VALUES ('a')",
      Statement.RETURN_GENERATED_KEYS);
ResultSet keys = stmt.getGeneratedKeys();
int primaryKey = -1;
if (keys.next()) {
    try (PreparedStatement keyStatement = 
           connection.prepareStatement("SELECT ID FROM theTable WHERE ROWID = ?")) {
        keyStatement.setRowId(keys.getRowId(1));
        try (ResultSet rs = keyStatement.executeQuery()) {
             primaryKey = rs.getInt(1);
        }
    }
}

答案 1 :(得分:1)

除了@Mark Rotteveel提供的解决方案之外,您还可以使用Connection.prepareStatement(String, String[])指定要从中返回值的确切列。在这种情况下,如果您为主键提供列名,则该值将位于从Statement.getGeneratedKeys返回的ResultSet中。

另一种选择是从序列中获取主键的值,并作为insert语句的一部分插入,而不是使用触发器:

select mysequence.nextval from dual