powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Одно соединение на все методы.
25 сообщений из 29, страница 1 из 2
Одно соединение на все методы.
    #38484825
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте. Необходимо сделать так, чтобы программа использовала только одно соединение с БД MySQL. Но проблема в том, что в программе есть класс в котором несколько методов работы с БД. В одних методах это просто чтение данных, в других запись. Но дело в том что все эти методы могут вызываться из разных потоков. Можно ли сделать так? И не будет ли проблем при вызове из synchronized блока метода с synchronized того-же объекта? Спасибо!
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
Connection mConnection;

public void method1(....){
   synchronized(mConnection){
         Что-то делаем...
   }
}

public void method2(....){
   synchronized(mConnection){
         Что-то делаем...
   }
}

public void method3(....){
   synchronized(mConnection){
         method1(...)
   }
}
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484828
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel,

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
public static class MySqlConnector {

    private static Connection conn;

    public static synchronized Connection getConnection(String connUrl) throws ClassNotFoundException, SQLException {
        if (conn == null || (conn != null && conn.isClosed())) {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(connUrl);
        }
        return conn;
    }
}
...
...
...
Connection conn = MySqlConnector.getConnection("jdbc:mysql://localhost/test");
ResultSet rs = conn.createStatement().executeQuery("...");
while (rs.next()) {
    System.out.println(rs.getString(1));
}
rs.close();
...
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484831
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UsmanGorloPavel,

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
public static class MySqlConnector {

    private static Connection conn;

    public static synchronized Connection getConnection(String connUrl) throws ClassNotFoundException, SQLException {
        if (conn == null || (conn != null && conn.isClosed())) {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(connUrl);
        }
        return conn;
    }
}
...
...
...
Connection conn = MySqlConnector.getConnection("jdbc:mysql://localhost/test");
ResultSet rs = conn.createStatement().executeQuery("...");
while (rs.next()) {
    System.out.println(rs.getString(1));
}
rs.close();
...



Спасибо! Но чем это отличается от просто объявления Connection mConnection и последующего открытия соединения к примеру в конструкторе? Что будет если поток №1 в методе №2 будет выполнять какую-нибудь хранимую процедуру, а в потоке №3 произойдет commit на этом единственном соединении? Спасибо.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484884
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Usman, ваше решение не удовлетворяет требованиям автора. Получение соединения синхронизировано, а работа с этим соединением нет.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484885
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavelМожно ли сделать так?Можно.
GorloPavelИ не будет ли проблем при вызове из synchronized блока метода с synchronized того-же объекта?Не будет.

P.S.: Другое дело, что такая работа с СУБД как минимум не эффективна, и я с трудом могу придумать сценарии, когда такое будет требоваться.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484887
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavelНо чем это отличается от просто объявления Connection mConnection и последующего открытия соединения к примеру в конструкторе?В конструкторе проинициализируется переменная mConnection и откроется соединение.GorloPavelЧто будет если поток №1 в методе №2 будет выполнять какую-нибудь хранимую процедуру, а в потоке №3 произойдет commit на этом единственном соединении?mConnection - синхронизирующий объект (монитор). Синхроблок заблокирует монитор при входе одного из потоков.
Другие потоки будут ожидать пока освободится mConnection.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484896
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UsmanGorloPavelНо чем это отличается от просто объявления Connection mConnection и последующего открытия соединения к примеру в конструкторе?В конструкторе проинициализируется переменная mConnection и откроется соединение.GorloPavelЧто будет если поток №1 в методе №2 будет выполнять какую-нибудь хранимую процедуру, а в потоке №3 произойдет commit на этом единственном соединении?mConnection - синхронизирующий объект (монитор). Синхроблок заблокирует монитор при входе одного из потоков.
Другие потоки будут ожидать пока освободится mConnection.
Т.е пока поток #1 будет работать с методом #1 поток #2 при вызове методa #2 будет ждать пока поток #1 не закончит выполнение метода #1?
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484898
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Т.е ваше решение будет работать так же?
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484904
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все равно не понимаю как в вашем случае такое возможно. Ведь getConnection вернет ссылку для потока №1 и выполнение метода продолжится дальше, а в этот момент ничего не мешает потоку №2 вызвать getConnection, получить туже ссылку и тоже начать что-то делать с БД, пока выполняется поток №1. Или я чего-то не понимаю?
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484923
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel ,
Повторюсь еще раз - решение Usman не работает так, как вы оно надо. Не работает . Логика работы с СУБД не синхронизирована. Более того, у него возможно одновременное существование нескольких разных соединений, которые не синхронизировано выполняют разные методы.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484929
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel,
Ваш код не предусматривает возможности пере-создания соединения. Пусть оно в системе одно. Но если произошло аварийное отключение, то можно ведь и пересоздать.

Пример от Usman показывает идею, но при этом не является потокобезопасным.

Лучше всего взять готовый пул соединений и настроить его на одно соединение максимум. Во-первых готовый пул уже достаточно безопасен и меньше шансов накосячить с кокурентной инициализацией и прочими радостями.
Во-вторых, ваш код перестанет быть привязан к логике "единственное соединени". Если вдруг нужно, "единственно" преващается в "множественное" простой настройкой пула.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484931
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavelВсе равно не понимаю как в вашем случае такое возможно. Ведь getConnection вернет ссылку для потока №1 и выполнение метода продолжится дальше, а в этот момент ничего не мешает потоку №2 вызвать getConnection, получить туже ссылку и тоже начать что-то делать с БД, пока выполняется поток №1. Или я чего-то не понимаю?Так и есть. След. пример подтверждение этому:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
for (int i = 1; i <= 5; i++) {
    final String threadName = "Thread #" + i;
    new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                try {
                    Statement stmt = MySqlConnector.getConnection("jdbc:mysql://localhost/test").createStatement(); 
                    ResultSet rs = stmt.executeQuery("show variables");
                    while (rs.next()) {
                        System.out.println(threadName + ": " + rs.getString(1));
                    }
                    rs.close();
                    stmt.close();
                } catch (Exception e) {
                    e.printStackTrace(System.out);
                }
            }
        }
    }).start();
}

И все в пределах одного соединения.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484936
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В идеале, если в системе действительно много потоков и нужно синхронизировать вообще всю работу с базой, а не только получение соединений, то имеет смысл всю работу с базой выстраивать в очередь и разгребать одним единственным потоком. Например через ExecutorService и Future.
Можно попробовать через Continuation сделать. Которого на pure Java пока нет. Но есть либы, тогда не придется логику методов разрывать для огранизации очереди.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484954
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczВ идеале, если в системе действительно много потоков и нужно синхронизировать вообще всю работу с базой, а не только получение соединений, то имеет смысл всю работу с базой выстраивать в очередь и разгребать одним единственным потоком. Например через ExecutorService и Future.
Можно попробовать через Continuation сделать. Которого на pure Java пока нет. Но есть либы, тогда не придется логику методов разрывать для огранизации очереди.
Да, проще говоря мне нужно чтобы все запросы к БД были по очереди. Не асинхронно.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484959
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мой вариант, который первом посте не подходит?
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484961
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavelМой вариант, который первом посте не подходит?В method3() может произойти DeadLock:
Код: java
1.
2.
3.
4.
5.
public void method3(....){
   synchronized(mConnection){
         method1(...)
   }
}
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484962
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UsmanGorloPavelМой вариант, который первом посте не подходит?В method3() может произойти DeadLock:
Код: java
1.
2.
3.
4.
5.
public void method3(....){
   synchronized(mConnection){
         method1(...)
   }
}


На уровне JVM или СУБД?
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484965
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavelНа уровне JVM или СУБД?На уровне JVM
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484966
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavelНа уровне JVM или СУБД?Дедлок на мониторах в JVM может произойти только в одном случае:
1) Есть больше чем один монитор
2) Захват этих нескольких мониторов из разных методов происходит неупорядоченно.

В вашем примере монитор только один, следовательно дедлок невозможен ни при каких условиях.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484967
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvGorloPavelНа уровне JVM или СУБД?Дедлок на мониторах в JVM может произойти только в одном случае:
1) Есть больше чем один монитор
2) Захват этих нескольких мониторов из разных методов происходит неупорядоченно.

В вашем примере монитор только один, следовательно дедлок невозможен ни при каких условиях.
Значит мой вариант жизнеспособен?
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484979
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UsmanGorloPavelНа уровне JVM или СУБД?На уровне JVMDeadLock'а не будет. Проверил. Сорри.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484984
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel,
Откуда потоки если надо синхронно.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484990
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123GorloPavel,
Откуда потоки если надо синхронно.
Клиентские подключения, tcp сессии. Мне нужно синхронно выполнять некоторые вещи.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484995
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavelЗначит мой вариант жизнеспособен?Жизнеспособен за исключением одного но. Он жизнеспособен, если вы всегда работаете с одним и тем же коннекшном. Если же, например, у вас он сдох, и надо пересоздать новый, то как раз здесь вы можете получить букет проблем с дедлоками и прочей многопоточной хренью. Как уже сказал Blazkowicz, надо смотреть в сторону пула соединений, который снимет вас всю головную боль касательно многопоточности.
...
Рейтинг: 0 / 0
Одно соединение на все методы.
    #38484999
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel, задание странное. Даже самые лютые и суровые DBA-шники позволяют 2-4 физ. соединения создать.
Вам с пулом на 1 соедиенние надо понимать что могут быть состояния когда с вашей стороны уже активности
нет а пул всё еще не доступен.
...
Рейтинг: 0 / 0
25 сообщений из 29, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / Одно соединение на все методы.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]