Страницы

Поиск по вопросам

суббота, 8 февраля 2020 г.

Thread и jdbc одно соединение

#java #mysql #многопоточность


Не знаю многих нюансов в Java. Интересует, можно ли создать одно соединение с mysql
и работать с ним в потоках, или в каждом потоке, нужно создавать дополнительный экземпляр
соединения? Более 30 потоков, приводит к ошибке mysql: Too many connections. Снял ограничение
mysql, такким образом: 

set global max_connections = 200;


Но это не выход и хотелось бы знать на будущие, как правильно. 
Вот код:

   public class ParserMain {
        public static void main(String[] args) throws java.io.IOException {
            // Общее число сообщений
            int total_entries = 12000;
            // Кол-во потоков
            int thread_count = 25;
            // Кол-во записей на поток
            int entries_thread = total_entries / thread_count;
            // Начальный инкремент потока
            int thread_end;
            // Конечный инкремент потока
            int thread_start;

            for (int i = 1; i <= thread_count; ++i) {
                thread_end = i * entries_thread;
                thread_start = thread_end - entries_thread;
                new ParserThread(thread_start, thread_end).start();
            }
        }
    }

    public class ParserThread extends Thread {
        private int jstart;
        private int jend;

        protected Connection conn;
        protected PreparedStatement ps;
        protected Statement st;
        protected ResultSet rs;

        public ParserThread(int jstart, int jend) {
            this.jstart = jstart;
            this.jend = jend;
        }

        public void run() {
            String dbDriver = "org.gjt.mm.mysql.Driver";
            String dbHost = "jdbc:mysql://localhost/test?autoReconnect=true";

            try {
                Class.forName(dbDriver);
                conn = DriverManager.getConnection(dbHost, "root", "");
            } catch (Exception e) {
                System.err.println(e.getMessage());
            }
        }
    }

    


Ответы

Ответ 1



Да можно создать как и многопоточное подключение к БД так и один поток используя синхронизированный метод(Что конечно не рационально с точки зрения производительности) Тут небольшое лирическое отступление: JDBC Drivers - является набор классов Java, который позволяет подключаться к определенной базе данных. JDBC Drivers реализует много интерфейсов JDBC. Когда ваш код использует данный драйвер JDBC, он на самом деле просто использует стандартные интерфейсы JDBC.Таким образом, вы можете изменять драйвер JDBC не изменяя кода Connections - после того, как Driver JDBC загружается и инициализируется, необходимо подключиться к базе данных. Это можно сделать, получив Connection к базе данных через JDBC API, и загруженный Driver. Вся связь с базой данных происходит через Connection. Приложение может иметь более одного Connection открытого к базе данных одновременно. Statements - используете для выполнения запросов и обновлений в базе данных. Есть несколько различных типов Statements. Каждый Statements соответствует одному запросу или обновлению. ResultSets - при выполнении запроса к базе данных вы получите обратно ResultSet. Вы можете пройти по ResultSet и прочитать результат запроса. Основной бонус от содержания ConnectionsPool(Пула готовых к работе соеденений) это отсутствие затрат на открытие каждого нового соединения.Такие готовые пулы представляют многие веб контейнеры.Да и написать свою реализацию в общем то обыденная задача.Лимиты с которыми Вы столкнулись вопрос СУБД... А вот минусы от использования многопоточного подключения это возможные неприятности связанные с параллельной записью или обращением в БД...Как то: потерянное обновление (lost update) — при одновременном изменении одного блока данных разными транзакциями, одно из изменений теряется; «грязное» чтение (dirty read) — чтение данных, добавленных или изменённых транзакцией, которая впоследствии не подтвердится (откатится); неповторяющееся чтение (non-repeatable read) — при повторном чтении в рамках одной транзакции, ранее прочитанные данные оказываются изменёнными; фантомное чтение (phantom reads) — Одна транзакция в ходе своего выполнения несколько раз выбирает множество строк по одним и тем же критериям. Другая транзакция в интервалах между этими выборками добавляет или удаляет строки или изменяет столбцы некоторых строк, используемых в критериях выборки первой транзакции, и успешно заканчивается. В результате получится, что одни и те же выборки в первой транзакции дают разные множества строк. Все в принципе лечиться уровнями изоляции транзакции.О чем рекомендую почитать отдельно...

Ответ 2



В классе который инициирует потоки реализуйте кэширующий метод для соединений к БД, аля такой: Connection getConnection() throws SQLException { Connection result; if (cnn != null) { result = cnn; } else { result = DriverManager.getConnection(connectionString); } return result; } далее при создании потоков передавайте им действующее соединение: Connection cnn = getConnection(); ParserThread parserThread = new ParserThread(cnn) ну и + стоит учесть синхронизацию вызовов метода чтобы не было Concurrency исключений

Комментариев нет:

Отправить комментарий