Ответ 1
Чтобы подробно рассказать о существующих ответах:
Объект PgJDBC Connection
является потокобезопасным, но только на уровне инструкций. Это не приведет к сбою или возникновению неправильного результата при использовании несколькими потоками в режиме autocommit, но не будет изолировать транзакции разных потоков для вас. В соответствии с документацией для этого вам нужно использовать пул соединений.
Существует множество способов использования соединений между несколькими потоками:
-
Используйте внутренний пул соединений, в котором вы получаете соединения, выполняете с ними работу и возвращаете их в пул. Это наиболее предпочтительный вариант для большинства приложений. Для Java существует множество реализаций пула соединений JDBC, поэтому не сворачивайте их самостоятельно. dbcp и c3p0 - две популярные реализации, но если вы используете сервлет-среду или сервер приложений, вы обычно должны использовать пул соединений с сервером, а не приносить свои собственные.
-
Используйте внешний пул соединений, например pgbouncer или pgpool-II, и свободно открывайте/закрывайте его. Это немного медленнее, и в основном это опция, используемая там, где приложение не может или по разным причинам не должно объединять соединения внутри. Вам, вероятно, не нужно это делать, если вам не нужно ограничивать общее количество подключений к БД и делиться ими между несколькими приложениями или экземплярами приложения.
-
Не используйте пул и открывайте/закрывайте соединения свободно. Это ужасно неэффективно. Не делайте этого.
-
Поддерживайте соединение в потоке, используя локальное хранилище потоков. Это будет работать, но оно крайне неэффективно, потому что каждое открытое соединение связывает ресурсы сервера базы данных, когда он сидит без дела. Не делайте этого, если вы не используете внешний пул соединений, например PgBouncer, в режиме пула транзакций, и в этом случае это нормально.
-
Используйте только одно соединение и завершайте транзакции в блоках
synchronized
, синхронизируя в экземпляреConnection
. Это будет работать и будет эффективно использовать соединение с базой данных, но ограничит производительность ваших потоков. Это вообще не хороший дизайн ни для чего, кроме игрушек/удобных приложений. -
Используйте только одно соединение со своим выделенным потоком. Другие подключения передают структуры данных, описывающие работу над этим потоком через очередь FIFO, стиль производителя/потребителя. Это работает, если потоки тратят большую часть своего времени на работу с процессором или другую работу без базы данных и нуждаются только в ограниченном доступе к базе данных. По большей части единственная причина использовать его вместо использования пула соединений - это если вы ограничены использованием одного соединения по какой-то внешней причине, но если вы тогда, то это может быть достойным вариантом.
В общем, вы должны просто использовать пул соединений и сделать с ним.