[Java] なぜ、DBコネクションをマルチスレッドで共有してはいけないのか

2020年10月5日月曜日

Java Oracle PostgreSQL SQL

マルチスレッドでDBにアクセスする場合、各スレッドごとにコネクションプールからコネクションを取得する形式が多い。
DBコネクションはマルチスレッドで共有しない方がいいと言われるけど、なぜ共有してはいけないんだろうか。

いくつかのDBMSの説明を見てみよう。

Oracle

Oracle Database JDBC Developer's Guide
JDBC and Multithreading
https://docs.oracle.com/database/121/JJDBC/apxtips.htm#JJDBC28949

これを見る限りでは、Oracleではコネクションはマルチスレッドをサポートしているけど、スレッドごとにコネクションを持つことを推奨している。
その理由としては、スレッドごとに処理がシリアライズされることによるパフォーマンス低下としている。

PostgreSQL

The PostgreSQL JDBC Interface
Chapter 10. Using the Driver in a Multithreaded or a Servlet Environment
https://jdbc.postgresql.org/documentation/head/thread.html

PostgreSQLでは、Oracleと違い、JDBCドライバはスレッドセーフではないと書かれている。
これでは、1つのコネクションをマルチスレッドで同時に使うと、パフォーマンス以前に処理がおかしくなってしまうだろう。

結論

そもそも、JDBCドライバがスレッドセーフでないDBMSもあるけど、仮にJDBCドライバがスレッドセーフだとしても、SQL関連の処理がシリアライズされてしまうので、結局マルチスレッド処理にしている旨味がない。
という訳で、DBコネクションはマルチスレッドで共有しない方がいいということになるんだね。