マルチスレッド システムでは、Java の単一の静的インスタンスがあります。 sql.Connection オブジェクトは無数の問題を引き起こす可能性があります。このアプローチでは、スレッドの安全性とリソース管理の両方の問題が生じます。
複数のスレッドが共有接続にアクセスすると、予期しない動作が発生する可能性があります。複数のスレッドがクエリを同時に実行するシナリオを考えてみましょう。
public static ResultSet searchUser(String user, String pass) { Connection conn = ConnectionPool.getConnection(); Statement stmt = conn.createStatement(); return stmt.executeQuery("SELECT * FROM users WHERE username='" + user + "' AND password='" + pass + "'"); }
スレッド A がクエリの実行中に、スレッド B が新しいクエリを開始した場合、最初のクエリが実行される前に 2 番目のクエリがデータベースを変更する可能性があります。完了。これにより、データの不整合や予測不可能な結果が発生する可能性があります。
アプリケーションの存続期間全体にわたって静的接続を維持すると、リソース管理に重大な問題が発生します。最初は 1 つの接続で十分ですが、ユーザー数が増えると、開いている接続が最終的にはタイムアウトになるか、接続プールの制限に達します。これにより、アプリケーションが新しい接続の確立に失敗し、最終的にその操作が停止する可能性があります。
スレッドの安全性と効率的なリソース管理の両方を確保するには、データベースを取得して解放することが重要です。可能な限り短いスコープ内の接続、通常は同じ try-with-resource ブロック内:
public User find(String username, String password) { User user = null; try ( Connection conn = dataSource.getConnection(); PreparedStatement statement = conn.prepareStatement("SELECT id, username, email FROM user WHERE username=? AND password=md5(?)"); ) { statement.setString(1, username); statement.setString(2, password); try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { user = new User(); user.setId(resultSet.getLong("id")); user.setUsername(resultSet.getString("username")); user.setEmail(resultSet.getString("email")); } } } return user; }
リソースを即座に閉じることで、スレッドがそれぞれの接続に干渉しないようにします。
接続パフォーマンスに懸念が残る場合は、接続プーリングの実装を検討してください。接続プーリングは、複数のスレッド間で共有できる事前に確立された接続のプールを維持します。これにより、パフォーマンスが大幅に向上し、リソースをより効率的に管理できます。
以上がマルチスレッド環境で静的 java.sql.Connection を使用するのは安全ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。