Является ли java.sql.Connection потокобезопасным? | for-each.dev
1. Обзор
Когда мы работаем над многопоточными проектами, мы знаем, что если несколько потоков совместно используют объекты, которые не реализованы с учетом безопасности потоков , потоки могут вести себя неожиданно .
Многие из нас, возможно, страдали от проблем с потокобезопасностью. Итак, вопрос «Является ли этот класс потокобезопасным?» часто приходит на ум.
Приложение Java довольно часто обращается к реляционным базам данных через JDBC, а также использует многопоточность. В этом кратком руководстве мы обсудим, является ли java.sql.Connection потокобезопасным.
2. Интерфейс
java.sql.ConnectionКогда мы получаем доступ к базам данных через JDBC из наших приложений, мы прямо или косвенно используем объекты java.sql.Connection . Мы полагаемся на эти объекты подключения для выполнения операций с базой данных. Поэтому java. — довольно важный тип в JDBC.
sql.Connection
Также распространен сценарий, когда несколько потоков должны одновременно обращаться к базе данных. В результате мы часто слышим вопрос: «Является ли java.sql.Connection потокобезопасным?»
В следующих нескольких разделах мы более подробно рассмотрим этот вопрос. Далее мы обсудим правильный подход к использованию объектов java.sql.Connection среди нескольких потоков, чтобы несколько потоков могли одновременно обращаться к базе данных.
3. Безопасность потоков и
java.sql.ConnectionПрежде всего, давайте быстро поговорим о безопасности потоков . Потокобезопасность — это метод программирования. То есть это концепция, связанная с реализацией. Следовательно, мы можем использовать различные методы, чтобы сделать реализацию потокобезопасной — например, реализации без сохранения состояния, неизменяемые реализации и т. д.
Теперь давайте посмотрим на java. . Во-первых, это интерфейс — он не содержит никакой реализации. Поэтому не имеет особого смысла спрашивать в общем: «Является ли
sql.Connectionjava.sql.Connection потокобезопасным?» Мы должны проверить классы, которые реализуют этот интерфейс, чтобы решить, является ли реализация потокобезопасной или нет.
Что ж, сразу возникает пара вопросов: Какие классы реализуют этот интерфейс? Являются ли они потокобезопасными?
Обычно мы не реализуем интерфейс java.sql.Connection в коде нашего приложения. Драйверы JDBC будут реализовывать этот интерфейс , чтобы мы могли получить соединение с определенной базой данных, такой как SQL Server или Oracle.
Таким образом, потокобезопасность реализации Connection полностью зависит от драйверов JDBC.
Далее в качестве примеров мы рассмотрим пару JDBC-драйверов баз данных.
4. Примеры реализации
java.sql.ConnectionMicrosoft SQL Server и Oracle Database — два широко используемых продукта реляционных баз данных.
В этом разделе мы рассмотрим драйверы JDBC этих двух баз данных и обсудим, являются ли их реализации интерфейса java.sql.Connection потокобезопасными.
4.1. Microsoft SQL-сервер
Класс драйвера Microsoft SQL Server, SQLServerConnection , реализует интерфейс java.sql.Connection и не является потокобезопасным, согласно его Javadoc:
> `SQLServerConnection` не является потокобезопасным, однако несколько инструкций, созданных из одного соединения, могут обрабатываться одновременно в параллельных потоках.
Таким образом, это означает, что мы не должны совместно использовать объект SQLServerConnection между потоками, но мы можем совместно использовать операторы, созданные из одного и того же объекта SQLServerConnection .
Далее давайте взглянем на другой известный продукт баз данных, Oracle Database.
4.2. База данных Oracle
Официальный драйвер Oracle JDBC реализует интерфейс java. потокобезопасным способом.
sql.Connection
Oracle заявляет о безопасности потоков своей реализации Connection в своем официальном документе :
Драйверы Oracle JDBC обеспечивают полную поддержку и оптимизированы для приложений, использующих многопоточность Java… Однако Oracle настоятельно не рекомендует совместное использование соединения с базой данных несколькими потоками. Избегайте одновременного доступа нескольких потоков к соединению…
Что ж, основываясь на приведенном выше описании, мы можем сказать, что реализация соединения Oracle является потокобезопасной. Однако совместное использование объекта соединения несколькими потоками «настоятельно не рекомендуется» .
Итак, из примеров SQL Server и Oracle мы знаем, что нельзя предполагать, что реализация является потокобезопасной. Затем мы можем спросить, каков правильный подход, если мы хотим, чтобы несколько потоков одновременно обращались к базе данных? Разберемся в следующем разделе.
5. Использование пула соединений
Когда мы обращаемся к базе данных из нашего приложения, нам нужно сначала установить соединение с базой данных. Это считается дорогостоящей операцией. Для повышения производительности обычно используется пул соединений .
Давайте быстро разберемся, как работает пул соединений в многопоточном сценарии.
Пул соединений содержит несколько объектов соединений. Мы можем настроить размер пула.
Когда нескольким потокам требуется одновременный доступ к базе данных, они запрашивают объекты соединения из пула соединений.
Если в пуле еще есть свободные соединения, поток получит объект соединения и начнет свои операции с базой данных. После того, как поток завершит свою работу, он вернет соединение в пул.
Если в пуле нет свободного соединения, поток будет ждать, пока объект соединения будет возвращен в пул другим потоком.
Таким образом, пул соединений позволяет нескольким потокам одновременно обращаться к базе данных, используя разные объекты соединения, вместо того, чтобы совместно использовать один и тот же объект .
Далее, таким образом, нам не нужно заботиться о том, является ли реализация интерфейса Connection потокобезопасной.
6. Заключение
В этой статье мы обсудили часто задаваемый вопрос: является ли java.sql.Connection потокобезопасным?
Поскольку java.sql.Connection является интерфейсом, непросто предсказать, являются ли его реализации потокобезопасными.
Более того, мы решили, что пул соединений — это правильный способ обработки соединений, если нескольким потокам требуется одновременный доступ к базе данных.
Документация JDK 20 — Главная
- Главная
- Ява
- Java SE
20
Обзор
- Прочтите меня
- Примечания к выпуску
- Что нового
- Руководство по миграции
- Загрузить JDK
- Руководство по установке
- Формат строки версии
Инструменты
- Технические характеристики инструментов JDK
- Руководство пользователя JShell
- Руководство по JavaDoc
- Руководство пользователя средства упаковки
Язык и библиотеки
- Обновления языка
- Основные библиотеки
HTTP-клиент JDK- Учебники по Java
- Модульный JDK
- Руководство программиста API бортового регистратора
- Руководство по интернационализации
Технические характеристики
- Документация API
- Язык и ВМ
- Имена стандартных алгоритмов безопасности Java
- банок
- Собственный интерфейс Java (JNI)
- Инструментальный интерфейс JVM (JVM TI)
- Сериализация
- Проводной протокол отладки Java (JDWP)
- Спецификация комментариев к документации для стандартного доклета
- Прочие характеристики
Безопасность
- Руководство по безопасному кодированию
- Руководство по безопасности
Виртуальная машина HotSpot
- Руководство по виртуальной машине Java
- Настройка сборки мусора
Управление и устранение неполадок
- Руководство по устранению неполадок
- Руководство по мониторингу и управлению
- Руководство по JMX
Client Technologies
- Руководство по специальным возможностям Java
maxPoolSize | целое число | Задает максимальное количество подключений, бассейн может иметь в данный момент времени. По умолчанию : 100 |
waitQueueTimeoutMS | 9012 1 целое число | Задает максимальное время в миллисекундах, в течение которого поток может ожидать, пока соединение станет доступным. По умолчанию : 120000 (120 секунд) |
serverSelectionTimeoutMS | 90 120 Задает максимальное количество времени в миллисекундах, в течение которого драйвер
будет ждать успешного выбора сервера, прежде чем бросить
исключение. 30000 (30 секунд) | |
localThresholdMS | целое число | При обмене данными с несколькими экземплярами MongoDB в реплике установлено, драйвер будет отправлять запросы только на сервер, чей время отклика меньше или равно серверу с самым быстрым время отклика плюс локальный порог в миллисекундах. По умолчанию : 15 |
heartbeatFrequencyMS | целое | Указывает частоту в миллисекундах, с которой драйвер будет ждать между попытками определить текущее состояние каждого сервер в кластере. По умолчанию : 10000 (10 секунд) |
Набор реплик | 90 121 строка | Указывает, что строка подключения
предоставляется включает несколько хостов. null |
ssl | логический 90 124 | Указывает, что вся связь с экземплярами MongoDB должна используйте TLS/SSL. Заменено опцией tls . По умолчанию : false |
tls | логический 90 124 | Указывает, что вся связь с экземплярами MongoDB должна используйте TLS. Заменяет вариант ssl . По умолчанию : ложь |
tlsInsecure | логическое значение | Указывает, что драйвер должен разрешать недопустимые имена хостов для TLS
связи. Имеет тот же эффект, что и настройка tlsAllowInvalidHostnames от до false |
tlsAllowInvalidHostnames | 90 121 логическое значение | Указывает, что драйвер должен разрешать недопустимые имена хостов в сертификат для TLS-соединений. Заменяет sslInvalidHostNameAllowed . По умолчанию : false |
connectTimeoutMS | целое число 901 24 | Определяет максимальное количество времени в миллисекундах, в течение которого Java
Драйвер ожидает открытия соединения до истечения времени ожидания. Значение 10000 (10 секунд) |
socketTimeoutMS | целое число | Задает максимальное количество времени в миллисекундах, в течение которого Java
Драйвер будет ждать отправки или получения запроса до истечения времени ожидания. 0 |
maxIdleTimeMS | целое число 90 124 | Определяет максимальное количество времени в миллисекундах, в течение которого Java
Драйвер позволит соединению в пуле бездействовать перед закрытием
связь. Значение 0 |
maxLifeTimeMS | целое число | Задает максимальное количество времени в миллисекундах,
Драйвер будет продолжать использовать объединенное соединение перед закрытием
связь. Значение 0 |
журнал | логическое значение | Указывает, что драйвер должен ожидать подключенную MongoDB. instance для групповой фиксации в файле журнала на диске для всех операций записи. По умолчанию : false |
w | строка или целое число 9012 4 | Указывает проблему записи. Дополнительные сведения о значениях см. документация сервера для опции w. По умолчанию : 1 |
wtimeoutMS | целое число | 901 20|
readPreference | строка | Задает предпочтение чтения. Дополнительные сведения о значениях см. документация по серверу опция readPreference. По умолчанию : основной |
readPreferenceTags | строка 9 0124 | Указывает теги предпочтения чтения. Дополнительные сведения о значениях см. документация по серверу Опция readPreferenceTags. По умолчанию : null |
maxStalenessSeconds | целое | Указывает в секундах, насколько устаревшим может быть вторичный
драйвер перестает связываться с этим вторичным. -1 |
authMechanism | строка | Указывает механизм проверки подлинности, который должен использовать драйвер, если учетные данные был поставлен. По умолчанию : По умолчанию клиент выбирает наиболее безопасный механизм доступен в зависимости от версии сервера. Для возможных значения см. в документации по серверу Опция механизма авторизации. |
authSource | строка | Указывает базу данных, для которой должны быть предоставлены учетные данные. admin |
authMechanismProperties | 9012 1 строка | Задает свойства аутентификации для указанной аутентификации механизм в виде списка свойств и значений, разделенных двоеточиями. Для получения дополнительной информации см. документацию сервера для параметр authMechanismProperties. По умолчанию : null |
appName | строка | Указывает имя приложения, предоставляемого экземплярам MongoDB. во время рукопожатия соединения. Может использоваться для журналов сервера и профилирование. По умолчанию : нуль |
компрессоры | строка | Указывает один или несколько алгоритмов сжатия, используемых драйвером. null |
zlibCompressionLevel | целое | Указывает степень сжатия Zlib.
следует использовать для уменьшения размера запросов к подключенной MongoDB
пример. Уровень может варьироваться от null |
retryWrites | логический 9 0124 | Указывает, что драйвер должен повторить поддерживаемые операции записи
если они выходят из строя из-за сетевой ошибки. true |
retryReads | логический | Указывает, что драйвер должен повторить поддерживаемые операции чтения если они выходят из строя из-за сетевой ошибки. По умолчанию : true |
uuidRepresentation | строка 9 0124 | Указывает представление UUID, используемое для чтения и записи. операции. Дополнительные сведения см. в документации драйвера. для Метод MongoClientSettings.getUuidRepresentation(). По умолчанию : не указано |
прямое соединение | логическое значение | Указывает, что драйвер должен подключаться к хосту напрямую. |

По умолчанию : 
Когда указано, драйвер
пытается найти всех членов этого множества.
Настройка безопасности TLS
ограничения другими способами, используйте
пользовательский SSLContext.
Значение 
Значение
Минимальное значение
либо 90 секунд, либо частота сердечных сокращений плюс 10 секунд, в зависимости от того, что
лучше. Для получения дополнительной информации см. документацию сервера для
Параметр maxStalenessSeconds.
Отсутствие параметра или явное указание
проверено против.
попытается использовать для сжатия запросов, отправленных на подключенный
Экземпляр MongoDB. Возможные значения включают: 
