Почему соединение с базой данных закрывается после каждой операции - PullRequest
0 голосов
/ 01 апреля 2012

Я использую пул соединений в TOmcat 6, и я настроил этот способ в файле context.xml

<Resource name="jdbc/myoracle" auth="Container"
              type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
              url="jdbc:oracle:thin:@127.0.0.1:1521:ORCLE"
              username="scott" password="tiger" maxActive="20" maxIdle="10"
              maxWait="-1"/> 

И это мой класс Factory для получения соединения с использованием источника данных

public class ConnPoolFactory {
    private static DataSource dataSource;
    private static Connection connection;

    private ConnPoolFactory() {
    }

    public static synchronized Connection getConnection() throws SQLException {

        try {

            if (connection == null) {
                Context initContext = new InitialContext();
                Context envContext = (Context) initContext
                        .lookup("java:/comp/env");
                dataSource = (DataSource) envContext.lookup("jdbc/myoracle");
                connection = dataSource.getConnection();
            } else {
                return connection;
            }

        } catch (NamingException e) {
            e.printStackTrace();
        }

        return connection;

    }
}

И из моего сервлета внутри блока finally я закрываю его таким образом

try {

connection = ConnPoolFactory.getConnection();
finally

{

if(conn!=null)
con.close();
}

Из моего пользовательского интерфейса я могу давать различные команды (нажатие кнопки), такие как Вставка, Обновление, Удалить, Выбрать --.

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

Если я удаляю этот блокирующий код внутри моего сервлета, то приложение работает нормально для любого количества команд

Может кто-нибудь, пожалуйста, дайте мне знать, что не так с этим блоком finnaly ??

Ответы [ 2 ]

1 голос
/ 02 апреля 2012

Переменная Connection в ConnPoolFactory должна быть локальной, а не статической.Переменная, которую вы должны проверить на null, это не connection, а dataSource.Получив ненулевое значение, вы возвращаете dataSource.getConnection().После этого вызывающий абонент должен закрыть это соединение.

0 голосов
/ 01 апреля 2012

Ваш завод не знает, что соединение закрыто, и продолжает раздавать его. Я предполагаю, что это то, что вы имели в виду, проектируя это.

Ваш сервлет должен либо вернуть соединение после использования, либо каждый раз на заводе создается новое соединение.

Редактировать: пытается быть более явным:

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

Кстати, вы можете столкнуться с еще одной неприятной ошибкой, если не закроете свое соединение: вы будете совместно использовать соединение между потоками сервлета, если два запроса приходят одновременно, что может или не может работать в зависимости от того, какие операции с БД вы выполняете. 1009 *

...