Является ли java.sql.Connection потокобезопасным? | for-each.dev
1. Обзор
Когда мы работаем над многопоточными проектами, мы знаем, что если несколько потоков совместно используют объекты, которые не реализованы с учетом безопасности потоков , потоки могут вести себя неожиданно .
Многие из нас, возможно, страдали от проблем с потокобезопасностью. Итак, вопрос «Является ли этот класс потокобезопасным?» часто приходит на ум.
Приложение Java довольно часто обращается к реляционным базам данных через JDBC, а также использует многопоточность. В этом кратком руководстве мы обсудим, является ли java.sql.Connection
потокобезопасным.
2. Интерфейс
java.sql.Connection
Когда мы получаем доступ к базам данных через JDBC из наших приложений, мы прямо или косвенно используем объекты java.sql.Connection
. Мы полагаемся на эти объекты подключения для выполнения операций с базой данных. Поэтому java. sql.Connection
— довольно важный тип в JDBC.
Также распространен сценарий, когда несколько потоков должны одновременно обращаться к базе данных. В результате мы часто слышим вопрос: «Является ли java.sql.Connection
потокобезопасным?»
В следующих нескольких разделах мы более подробно рассмотрим этот вопрос. Далее мы обсудим правильный подход к использованию объектов java.sql.Connection
среди нескольких потоков, чтобы несколько потоков могли одновременно обращаться к базе данных.
3. Безопасность потоков и
java.sql.Connection
Прежде всего, давайте быстро поговорим о безопасности потоков . Потокобезопасность — это метод программирования. То есть это концепция, связанная с реализацией. Следовательно, мы можем использовать различные методы, чтобы сделать реализацию потокобезопасной — например, реализации без сохранения состояния, неизменяемые реализации и т. д.
Теперь давайте посмотрим на java. sql.Connection
. Во-первых, это интерфейс — он не содержит никакой реализации. Поэтому не имеет особого смысла спрашивать в общем: «Является ли java.sql.Connection
потокобезопасным?» Мы должны проверить классы, которые реализуют этот интерфейс, чтобы решить, является ли реализация потокобезопасной или нет.
Что ж, сразу возникает пара вопросов: Какие классы реализуют этот интерфейс? Являются ли они потокобезопасными?
Обычно мы не реализуем интерфейс java.sql.Connection
в коде нашего приложения. Драйверы JDBC будут реализовывать этот интерфейс , чтобы мы могли получить соединение с определенной базой данных, такой как SQL Server или Oracle.
Таким образом, потокобезопасность реализации Connection
полностью зависит от драйверов JDBC.
Далее в качестве примеров мы рассмотрим пару JDBC-драйверов баз данных.
4. Примеры реализации
java.sql.Connection
Microsoft 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
- Руководство пользователя средства упаковки
Язык и библиотеки
- Обновления языка
- Основные библиотеки
- Учебники по 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 | целое | Указывает в секундах, насколько устаревшим может быть вторичный
драйвер перестает связываться с этим вторичным. Минимальное значение
либо 90 секунд, либо частота сердечных сокращений плюс 10 секунд, в зависимости от того, что
лучше. Для получения дополнительной информации см. документацию сервера для
Параметр maxStalenessSeconds.
Отсутствие параметра или явное указание -1 |
authMechanism | строка | Указывает механизм проверки подлинности, который должен использовать драйвер, если учетные данные был поставлен. По умолчанию : По умолчанию клиент выбирает наиболее безопасный механизм доступен в зависимости от версии сервера. Для возможных значения см. в документации по серверу Опция механизма авторизации. |
authSource | строка | Указывает базу данных, для которой должны быть предоставлены учетные данные. проверено против. По умолчанию : admin |
authMechanismProperties | 9012 1 строка | Задает свойства аутентификации для указанной аутентификации механизм в виде списка свойств и значений, разделенных двоеточиями. Для получения дополнительной информации см. документацию сервера для параметр authMechanismProperties. По умолчанию : null |
appName | строка | Указывает имя приложения, предоставляемого экземплярам MongoDB. во время рукопожатия соединения. Может использоваться для журналов сервера и профилирование. По умолчанию : нуль |
компрессоры | строка | Указывает один или несколько алгоритмов сжатия, используемых драйвером. попытается использовать для сжатия запросов, отправленных на подключенный
Экземпляр MongoDB. Возможные значения включают: null |
zlibCompressionLevel | целое | Указывает степень сжатия Zlib.
следует использовать для уменьшения размера запросов к подключенной MongoDB
пример. Уровень может варьироваться от null |
retryWrites | логический 9 0124 | Указывает, что драйвер должен повторить поддерживаемые операции записи если они выходят из строя из-за сетевой ошибки. По умолчанию : true |
retryReads | логический | Указывает, что драйвер должен повторить поддерживаемые операции чтения если они выходят из строя из-за сетевой ошибки. По умолчанию : true |
uuidRepresentation | строка 9 0124 | Указывает представление UUID, используемое для чтения и записи. операции. Дополнительные сведения см. в документации драйвера. для Метод MongoClientSettings.getUuidRepresentation(). По умолчанию : не указано |
прямое соединение | логическое значение | Указывает, что драйвер должен подключаться к хосту напрямую. |