Последовательные операторы JDBC не выполняют транзакции

1

У меня есть следующие таблицы:

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? Я неправильно использую API JDBC?

Теги:
sql-server
tsql
jdbc
transactions

1 ответ

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);
  • 0
    Спасибо @dasblinkenlight (+1) - ваш ответ имеет смысл, однако я получаю тот же результат даже после добавления ваших rs.next() . Есть идеи? Еще раз спасибо!
  • 1
    @IAmYourFaja Это действительно странно ... Вы видите число, когда запускаете SELECT IDENT_CURRENT('myapp_users') в анализаторе запросов, верно?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню