使用 JDBC 选择“更新”?

Posted

技术标签:

【中文标题】使用 JDBC 选择“更新”?【英文标题】:select "for update" with JDBC? 【发布时间】:2018-04-10 05:54:58 【问题描述】:

我想使用 JDBC 在 Java 中创建 for update select 语句,但不确定如何完成。

如果您对更新不熟悉,可以在此处阅读 https://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-FOR-UPDATE-SHARE

例如,我有以下选择语句

我的选择语句

select email from email_accounts where already_linked = false order by random() limit 1

我的更新声明

UPDATE email_accounts set already_linked = true, account_link_timestamp = now() where email = ?

在使用 for update 的同时使用 JDBC 在 Java 中如何做到这一点?

【问题讨论】:

【参考方案1】:

您首先将for update 添加到您的选择(以及您要更新的其他列)中,然后更新它们。此外,如 cmets 中所述,请确保您的 getConnection 在没有自动提交的情况下返回 Connection。并且您需要设置一个Statement 滚动类型和CONCUR_UPDATABLE。类似的,

String[] colNames =  "email", "already_linked", "account_link_timestamp" ;
String query = "select " + Stream.of(colNames).collect(Collectors.joining(", "))
        + "from email_accounts where already_linked = false for update";
try (Connection conn = getConnection(); // Make sure conn.setAutoCommit(false);
        Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 
                ResultSet.CONCUR_UPDATABLE);
        ResultSet rs = stmt.executeQuery(query)) 
    while (rs.next()) 
        // Get the current values, if you need them.
        String email = rs.getString(colNames[0]);
        boolean linked = rs.getBoolean(colNames[1]);
        Timestamp time = rs.getTimestamp(colNames[2]);
        // ...
        rs.updateBoolean(colNames[1], true);
        rs.updateTimestamp(colNames[2], //
                new Timestamp(System.currentTimeMillis()));
        rs.updateRow();
    
 catch (SQLException e) 
    e.printStackTrace();

【讨论】:

conn.setAutoCommit = false 是否需要 for update 锁才能生效,还是没关系? 另外,createStatement 不需要用ResultSet.CONCUR_UPDATABLE 调用,所以updateRow 可以工作吗? @GordThompson 很好,谢谢。是的。到了晚餐时间,我有点赶时间。 conn.setAutoCommit(false); 在 while 循环上方可以吗? 您可能需要在 SELECT 中包含主键列,以使结果集可通过 JDBC 更新,即将其添加到 colNames

以上是关于使用 JDBC 选择“更新”?的主要内容,如果未能解决你的问题,请参考以下文章

插入、替换/更新 JDBC

JDBC连接(MySql)数据库步骤,以及查询插入删除更新等十一个处理数据库信息的功能

JDBC:空/空结果集?

通过 JDBC-ODBC 驱动程序从 Access 中选择时不显示丹麦语字符 [重复]

使用 jdbc 语句创建和选择语句

使用 JDBC 在 Android 中选择