【问题标题】:Java JDBC Primary Key Oracle DatabaseJava JDBC 主键 Oracle 数据库
【发布时间】:2014-06-10 08:26:11
【问题描述】:

我正在使用 Java 开发一个应用程序,并且我有一个 Oracle 数据库。为了存储数据,我使用 JDBC。在 Oracle 数据库中,没有什么能比得上自动增量。所以我使用触发器来获取最新的主键。

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

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

在同一个线程中输入另一个方法需要这个主键。

【问题讨论】:

  • 为什么不能使用oracle sequences 而不是触发器
  • 如何将数据持久化到 Oracle 表中?即您使用存储过程还是 DML 语句?
  • 我不记得名字了,但是是的,序列和触发器都被使用了。
  • 我使用 PreparedStatement 和 SELECT 等 SQL 查询。
  • @user3189663 序列不受事务控制,如果同时执行多个插入操作,使用 SELECT sequenceName.CURRVAL FROM DUAL 选择主键可能会产生错误的结果。

标签: java oracle jdbc concurrency


【解决方案1】:

检索主键的正确方法是使用getGeneratedKeys 工具(可以通过使用Statement.RETURN_GENERATED_KEYS 值和Statement.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);
        }
    }
}

【讨论】:

    【解决方案2】:

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

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

    select mysequence.nextval from dual
    

    【讨论】:

      猜你喜欢
      • 2013-09-02
      • 2014-06-16
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 2021-10-24
      • 2014-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多