Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > JNDI-JDBC - как вернуть коннект?


Автор: Се ля ви 27.8.2005, 18:02
Сначала устанавливал всегда прямые соединения с базой из веб-приложения, но из-за более чем "желательной" работы метода finalize в своё время поимел кучу проблем с незакрытыми коннеутами к базе, по-этому знакомый посоветовал получать коннекты к базе через пул соединений с помощью JNDI.

Я написал такой код:
Код

interface Operation {
        Object doIt(Statement stmt) throws NamingException, SQLException;
    }

    //Выполнение метода, заложенного в передаваемый объект, реализующий интерфейс Operation, через пул соединений с базой данных.
    private Object executeOperation(Operation obj) throws NamingException, SQLException {

        Statement stmt;
        Object result = null;

        Context namingContext;
        DataSource ds;
        Connection aConnection;

        namingContext = new InitialContext();

        ds = (DataSource) namingContext.lookup(jndiDSName); // NamingException if CPool does not exists

        aConnection = ds.getConnection(); // SQLException if Connection is not created

        try {

            stmt = aConnection.createStatement(); // SQLException if Statement is not created

            try {

                result = obj.doIt(stmt); //SQLException

            } finally {

                stmt.close(); //SQLException if Statement is not closed

            }

        } finally {

            aConnection.close(); //SQLException if Connection is not closed
        }


        return result;
    }


Т.е. для каждой операции/группы операций с базой ищется коннект, передаётся методу, который "это делает" и потом конект закрывается и выходит за область видимости переменная, которая за него отвечает - значит, он должен стать добычей сборщика мусора, который и должен освободить конекшн для другого процесса.
Но коннекты, блин, копятся... Не пойму - почему. smile

Автор: Се ля ви 27.8.2005, 20:02
Отбой тревоги. Я сам контекст забыл закрыть.

Вот правильный код защищённого доступа к JDBC через JNDI:
Код


interface Operation {
        Object doIt(Statement stmt) throws NamingException, SQLException;
    }

    //Выполнение метода, заложенного в передаваемый объект, реализующий интерфейс Operation, через пул соединений с базой данных.
    private Object executeOperation(Operation obj) throws NamingException, SQLException {

        Statement stmt;
        Object result = null;

        Context namingContext;
        DataSource ds;
        Connection aConnection;

        namingContext = new InitialContext();

        try {

            ds = (DataSource) namingContext.lookup(jndiDSName); // NamingException if CPool does not exists

            aConnection = ds.getConnection(); // SQLException if Connection is not created

            try {

                stmt = aConnection.createStatement(); // SQLException if Statement is not created

                try {

                    result = obj.doIt(stmt); //SQLException

                } finally {

                    stmt.close(); //SQLException if Statement is not closed

                }

            } finally {

                aConnection.close(); ///SQLException if Connection is not closed
            }

        } finally {

            namingContext.close(); // NamingException
        }

        return result;
    }



Обращение к нему, соответственно, может быть таким:
Код

    // Выдать номер по id
    public int getNumberByID(final int Id) throws NamingException, SQLException {

        return
            (
                (Integer)
                    executeOperation(
                        new Operation() {

                            public Object doIt(Statement stmt) throws NamingException, SQLException {

                                ResultSet rs =
                                    stmt.executeQuery(
                                        "select num " +
                                        "from tbl1 " +
                                        "where id = " + Id
                                );

                                if (!rs.next())
                                    throw new SQLException("This number does not exists");

                                return new Integer(rs.getString(1))
                            }
                        }
                    )
            )
                .intValue();
    }


P.S. А прямые коннекты к базе - это, IMHO, для небольших программулек...

Автор: DEMO_VERSION 18.10.2005, 12:19
No eto znachit chto y menya dolzhen but' zapyshen server?? Dolzhno but EJB???

Kakoe znacenie jndiDSName???
ds = (DataSource) namingContext.lookup(jndiDSName);


Posmotrite primer ispolzovaniya Proxool
http://proxool.sourceforge.net/quickStart.html

Znachit li eto cho esli ya zahocy vupolnit kakojto SQL i mne nado bydet polycit Statement ili PreparedStatement mne nado bydet pisat vnytri fynkcui :
Код

Connection connection = null;
 2.try {
 4.  try {
 5.    connection = DriverManager.getConnection("proxool.example");
 6.  } catch (SQLException e) {
 7.    LOG.error("Problem getting connection", e);
 8.  }

a potom yzhe zakruvat i Statement i Connection?????

PS: y menya pokamis ne Web programa a prostaya konsolnaya.


Автор: Се ля ви 21.10.2005, 11:31
Цитата(DEMO_VERSION @ 18.10.2005, 12:19)
eto znachit chto y menya dolzhen but' zapyshen server??

Обычно - да. По крайней мере, в моём варианте было так. Либо самописный какой-нить Пул...

Цитата(DEMO_VERSION @ 18.10.2005, 12:19)
Dolzhno but EJB???

EJB тут абсолютно ни при чём.

Цитата(DEMO_VERSION @ 18.10.2005, 12:19)
Kakoe znacenie jndiDSName???

У меня это константа, определяется при настройках твоего пула, ты её сам задаёшь, а потом сюда прописываешь smile

А вообще, почитайте сначала про JNDI, например - http://forum.vingrad.ru/index.php?showtopic=45382. ;)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)