Используйте два соединения по отдельности для выбора сгустка и обновления статуса. Это нормально? - PullRequest
0 голосов
/ 12 декабря 2011
  private Clob getClob() throws exception{
    Connection conn = null;
    PreparedStatement pStmt = null;
    try {
        conn = getConnection();
        pStmt = conn.prepareStatement("SELECT REFERENCE FROM TEST WHERE ID = ? FOR UPDATE OF REFERENCE");
        pStmt.setLong(1,1);
        ResultSet rset = pStmt.executeQuery();
        while (rset.next()) {
               Clob clob = rset.getClob(1);
               Writer writer = clob .getCharacterOutputStream();
               writer.write("string to be updated");
               writer.flush();
               writer.close();
               return clob;
        }
        return null;        
    } finally {
        cleanup(conn, pStmt, rset);
    }
 }

  public void updateClob() throws exception{
    Clob clob = getClob();

    Connection conn = null;
    PreparedStatement pStmt = null;
    try {
        conn = getConnection();
        pStmt = conn.prepareStatement("UPDATE TEST SET REFERENCE = ? WHERE ID = ?");
        pStmt.setLong(1,1);
        pStmt.setClob(2,clob );
        pStmt.executeUpdate();
    } finally {
        cleanup(conn, pStmt, null);
    }
 }

Как видите, я использовал два соединения по отдельности для открытия и обновления Clob. из метода getClob:

Сначала я открываю соединение, чтобы прочитать локатор Clob, а затем освобождаю соединение, в следующем методе updateClob Я обновил clob (он откроет другое соединение),

Мой вопрос заключается в это нормально? нет проблем? потому что я видел много примеров кодов, которые использовали одно и то же соединение для выбора и обновления статистики.

Ответы [ 3 ]

0 голосов
/ 12 декабря 2011

Да, вам следует избегать создания нескольких соединений, поскольку ресурсы базы данных ограничены и должны использоваться с осторожностью.

Учитывая ваш вариант использования, я бы посоветовал не создавать соединение, а реорганизовать ваш код, чтобы улучшить управление соединениями.

Например, поскольку updateClob является публичным методом, я предполагаю, что он может быть вызван из другого потока кода, поэтому в приведенном ниже фрагменте кода соединение инициализируется в этом методе, а фактическая работа выполняется private методами, которые просто используют предоставленное им соединение и не создавайте новое.

Кроме того, они не закрывают передаваемое им соединение, они оставляют вызывающему соединение управление соединением, они просто закрывают все, что создают в этом случае PreparedStatement.

Фрагмент кода:

private void getAndUpdateClob(Connection conn) throws Exception {
    Clob clob = getClob(conn);
    PreparedStatement pStmt = null;
    try {
        pStmt = conn.prepareStatement("UPDATE TEST SET REFERENCE = ? WHERE ID = ?");
        pStmt.setLong(1, 1);
        pStmt.setClob(2, clob);
        pStmt.executeUpdate();
    } catch (SQLException sqlExp) {
        sqlExp.printStackTrace();
        throw sqlExp;
    } finally {
        if (pStmt != null) {
            pStmt.close();
        }
    }
}
private Clob getClob(Connection conn) throws Exception {
    PreparedStatement pStmt = null;
    try {
        pStmt = conn.prepareStatement("SELECT REFERENCE FROM TEST WHERE ID = ? FOR UPDATE OF REFERENCE");
        pStmt.setLong(1, 1);
        ResultSet rset = pStmt.executeQuery();
        while (rset.next()) {
            Clob clob = rset.getClob(1);
            Writer writer = clob.getCharacterOutputStream();
            writer.write("string to be updated");
            writer.flush();
            writer.close();
            return clob;
        }

    } catch (SQLException sqlExp) {
        sqlExp.printStackTrace();
        throw sqlExp;
    } finally {
        if (pStmt != null) {
            pStmt.close();
        }
    }
    return null;
}

public void updateClob() throws Exception {
    Connection conn = null;
    try {
        conn = getConnection();
        getAndUpdateClob(conn);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (conn != null) {
            conn.close();
        }
    }
}
0 голосов
/ 12 декабря 2011

Вы ничего не делаете в обновлении, кажется.Вы получаете текущий клоб в базе данных, а затем вставляете его обратно.В идеале это будет новый clob, не так ли в вашем обновлении?В противном случае, отдельное соединение для получения и обновления (отдельный интерфейс или метод, предусмотренный, чтобы сказать), не самое главное.

0 голосов
/ 12 декабря 2011

вы можете объявить Connection перед вызовом getClob и передать его как parameter, оно будет инициализировано в getClob, а затем то же, что вы можете использовать в updateClob.В противном случае вы также можете сделать это, объявив Connection как переменную метки Class.В этом случае вам не нужно много менять.Но не закрывайте соединение в getClob.пожалуйста, посмотрите код ниже:

private Clob getClob(Connection conn) throws exception{
    PreparedStatement pStmt = null;
    try {
        conn = getConnection();
        pStmt = conn.prepareStatement("SELECT REFERENCE FROM TEST WHERE ID = ? FOR UPDATE OF REFERENCE");
        pStmt.setLong(1,1);
        ResultSet rset = pStmt.executeQuery();
        while (rset.next()) {
               Clob clob = rset.getClob(1);
               Writer writer = clob .getCharacterOutputStream();
               writer.write("string to be updated");
               writer.flush();
               writer.close();
               return clob;
        }
    return null;        
    } finally {
        pStmt.close();
    }
 }

  public void updateClob() throws exception{
    Connection conn = null;
    Clob clob = getClob(conn);
    PreparedStatement pStmt = null;
    try {
        pStmt = conn.prepareStatement("UPDATE TEST SET REFERENCE = ? WHERE ID = ?");
        pStmt.setLong(1,1);
        pStmt.setClob(2,clob );
        pStmt.executeUpdate();
    } finally {
        cleanup(conn, pStmt, null);
    }
 }

другой метод, метка класса:

private Connection conn;
private Clob getClob() throws exception{
    PreparedStatement pStmt = null;
    try {
        conn = getConnection();
        pStmt = conn.prepareStatement("SELECT REFERENCE FROM TEST WHERE ID = ? FOR UPDATE OF REFERENCE");
        pStmt.setLong(1,1);
        ResultSet rset = pStmt.executeQuery();
        while (rset.next()) {
               Clob clob = rset.getClob(1);
               Writer writer = clob .getCharacterOutputStream();
               writer.write("string to be updated");
               writer.flush();
               writer.close();
               return clob;
        }
    return null;        
    } finally {
        pStmt.close();
    }
 }

  public void updateClob() throws exception{        
    Clob clob = getClob();
    PreparedStatement pStmt = null;
    try {
        pStmt = conn.prepareStatement("UPDATE TEST SET REFERENCE = ? WHERE ID = ?");
        pStmt.setLong(1,1);
        pStmt.setClob(2,clob );
        pStmt.executeUpdate();
    } finally {
        cleanup(conn, pStmt, null);
    }
 }

На самом деле это лучший метод, чем первый.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...