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ドライバーは、このインターフェイスを実装して、SQLServerやOracleなどの特定のデータベースへの接続を取得できるようにします。

したがって、 Connection 実装のスレッドセーフは、JDBCドライバーに完全に依存しています。

次に、例としていくつかのデータベースJDBCドライバーについて説明します。

4. java.sql.Connection実装例

Microsoft SQLServerとOracleDatabaseは、広く使用されている2つのリレーショナルデータベース製品です。

このセクションでは、これら2つのデータベースのJDBCドライバーを調べ、 java.sql.Connectionインターフェースの実装がスレッドセーフであるかどうかについて説明します。

4.1. Microsoft SQLServer

MicrosoftSQLServerドライバークラスSQLServerConnectionは、 java.sql.Connection インターフェイスを実装し、Javadocによるとスレッドセーフではありません。

SQLServerConnection はスレッドセーフではありませんが、単一の接続から作成された複数のステートメントを同時スレッドで同時に処理できます。

つまり、スレッド間でSQLServerConnectionオブジェクトを共有するべきではありませんが、同じSQLServerConnectionオブジェクトから作成されたステートメントを共有することはできます。

次に、もう1つの有名なデータベース製品であるOracleDatabaseを見てみましょう。

4.2. Oracleデータベース

公式のOracleJDBCドライバーは、java.sql.Connectionインターフェースをスレッドセーフな方法で実装します。

オラクルは、[X31X]公式文書で接続実装のスレッドセーフを述べています。

Oracle JDBCドライバーは、Javaマルチスレッドを使用するアプリケーションを完全にサポートし、高度に最適化されています…

ただし、Oracleは、複数のスレッド間でデータベース接続を共有することを強くお勧めします。 複数のスレッドが同時に接続にアクセスすることを許可しないでください…

上記の説明に基づいて、Oracleの接続実装はスレッドセーフであると言えます。 ただし、複数のスレッド間で接続オブジェクトを共有することは「強くお勧めしません」

したがって、SQL ServerとOracleの例から、java.sql.Connectionの実装がスレッドセーフであるとは想定できないことがわかります。 次に、複数のスレッドがデータベースに同時にアクセスする場合、適切なアプローチは何でしょうか。 次のセクションでそれを理解しましょう。

5. 接続プールの使用

アプリケーションからデータベースにアクセスするときは、最初にデータベースへの接続を確立する必要があります。 これはコストのかかる操作と見なされます。 パフォーマンスを向上させるために、通常、接続プールを使用します。

マルチスレッドシナリオで接続プールがどのように機能するかを簡単に理解しましょう。

接続プールは、複数の接続オブジェクトを保持します。 プールのサイズを構成できます。

複数のスレッドがデータベースに同時にアクセスする必要がある場合、それらは接続プールから接続オブジェクトを要求します。

プールにまだ空き接続がある場合、スレッドは接続オブジェクトを取得し、データベース操作を開始します。 スレッドが作業を終了すると、接続をプールに戻します。

プールに空き接続がない場合、スレッドは接続オブジェクトが別のスレッドによってプールに返されるのを待ちます。

したがって、接続プールを使用すると、同じオブジェクトを共有する代わりに、複数のスレッドが異なる接続オブジェクトを使用してデータベースに同時にアクセスできます

さらに、このように、Connectionインターフェースの実装がスレッドセーフであるかどうかを気にする必要はありません。

6. 結論

この記事では、よくある質問について説明しました。 java .sql.Connection はスレッドセーフですか?

java .sql.Connection はインターフェースであるため、実装がスレッドセーフであるかどうかを予測するのは簡単ではありません。

さらに、複数のスレッドがデータベースに同時にアクセスする必要がある場合、接続プールが接続を処理する適切な方法であることに対処しました。