顺序JDBC语句执行不进行交易

时间:2014-12-22 09:14:42

标签: 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?

1 个答案:

答案 0 :(得分:1)

SCOPE_IDENTITY不同,IDENT_CURRENT不关心事务或范围:它返回为表生成的最后一个标识密钥。

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

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

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);