java - 顺序 JDBC 语句执行不进行事务处理

标签 java sql-server tsql jdbc transactions

我有下表:

all_app_users
=============
all_app_user_id         INT PRIMARY KEY NOT NULL
is_enabled              BOOLEAN NOT NULL

myapp_users
===========
myapp_user_id           INT PRIMARY KEY NOT NULL
all_app_user_id         INT FOREIGN KEY (all_app_users)
myapp_user_stage        INT NOT NULL

以及以下 JDBC 代码:

Long allAppUserId = null;
Long myAppId = null;
Connection pooledConn = getPooledDBConnection();
PreparedStatement ps = null;
ResultSet rs = null;
try {
    ps = pooledConn.prepareStatement("INSERT INTO all_app_users ( is_enabled ) VALUES ( ? )");
    ps.setBoolean(1, true);
    ps.execute();
    ps.close();

    ps = pooledConn.prepareStatement("SELECT IDENT_CURRENT('all_app_users')");
    rs = ps.executeQuery();
    allAppUserId = (long)rs.getInt(0);
    rs.close();

    ps = pooledConn.prepareStatement("INSERT INTO myapp_users ( all_app_user_id, myapp_user_stage ) VALUES( ?, ? )");
    ps.setInt(1, Ints.checkedCast(allAppUserId));
    ps.setInt(2, 5);
    ps.execute();
    ps.close();

    ps = pooledConn.prepareStatement("SELECT IDENT_CURRENT('myapp_users')");
    rs = ps.executeQuery();
    myAppId = (long)rs.getInt(0);

    pooledConn.commit();

    System.out.println("Ping");
} catch(SQLException sqlExc) {
    logger.error(ExceptionUtils.getStackTrace(sqlExc));
    if(pooledConn != null) {
        try {
            pooledConn.rollback();
        } catch (SQLException e) {
            logger.error(ExceptionUtils.getStackTrace(e));
        }
    }
} finally {
    try {
        if(rs != null) {
            rs.close();
        }

        if(ps != null) {
            ps.close();
        }

        if(pooledConn != null) {
            pooledConn.close();
        }
    } catch (SQLException e) {
        logger.error(ExceptionUtils.getStackTrace(e));
    }
}

System.out.println("Pong");

当我运行该代码时,没有遇到任何异常,并且“Ping”和“Pong”消息打印到 STDOUT,但是 myAppId 为 NULL。 我想知道为什么?

也许这与我使用事务/提交有关?我应该在 4 个连续的 SQL 语句中的每一个之后提交吗?我是否错误地使用了 JDBC API?

最佳答案

SCOPE_IDENTITY 不同,IDENT_CURRENT 不关心事务或范围:它返回为表生成的最后一个身份 key 。

当表没有标识列、从未包含行或已被截断时,

IDENT_CURRENT 可以返回 NULL。这些都不适用于您的情况。但是,您似乎错误地运行了标量查询:在调用 rs.getInt(...) 之前,您从未调用过 rs.next():

ps = pooledConn.prepareStatement("SELECT IDENT_CURRENT('all_app_users')");
rs = ps.executeQuery();
rs.next(); // <<== Add this line
allAppUserId = (long)rs.getInt(0);
rs.close();

ps = pooledConn.prepareStatement("INSERT INTO myapp_users ( all_app_user_id, myapp_user_stage ) VALUES( ?, ? )");
ps.setInt(1, Ints.checkedCast(allAppUserId));
ps.setInt(2, 5);
ps.execute();
ps.close();

ps = pooledConn.prepareStatement("SELECT IDENT_CURRENT('myapp_users')");
rs = ps.executeQuery();
rs.next(); // <<== Add this line
myAppId = (long)rs.getInt(0);

关于java - 顺序 JDBC 语句执行不进行事务处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27599664/

相关文章:

java - 在每个元素上调用 remove() 以清空 ArrayList

java - 一个数的除数列表

sql - 查找不完全匹配 IN 条件列表的组

仅处理几 MB 数组时使用超过 512MB 的 PHP 脚本

TSQL 如何在用户定义的函数中输出 PRINT?

sql-server - 恢复 SQL Server 2005 数据库后将所有用户链接到登录

sql - 强制多个列之间的相互唯一性

java - Spring Boot 应用程序日志显示 iRAv2 格式日志

java - java中数组初始化时的栈和堆内存

c# - 在数据库 SQL 中计算平均值