JAVAやC#のデータベース接続プールの原理と応用

JAVAやC#のデータベース接続プーリング原理

、EFCore、SqlSugarの純コア:インターネットの現在の開発では、高い同時実行主流に、そのインターネットの現在の開発では、データベース操作やアクセスの最も重要な部分である、ORMフレームワークが悪いではない、などDapperの。JAVA春DataJpa(のEntityManager)、MyBatisの、MybatisPlus等

しかし、それは実際にはORM基本的に最低レベルのデータベースアクセスコンポーネント動作させるために来るとき:Ado.net、JDBCを

今日は、原則として2つのデータベースへのアクセスを接続プールをチャットに来て

データのAdo.netとJDBC接続プール、前に言えば、我々のデータベース接続プールが何であるかを理解するための最初の必要性

データベースサーバへの接続は、一般的にいくつかのステップの時間がかかります。接続された物理チャネルは、サーバが接続文字列情報を解析することが必要であると初期ハンドシェークでなければならない(例えばソケットまたは名前付きパイプなど)を確立する必要があり、現在のトランザクションに登録されなければならないチェックを実行するために、サーバによって認証されなければならない、などが挙げられます。

実際には、ほとんどのアプリケーションは、1つまたはいくつかの異なる接続構成を使用しています。アプリケーションの実行中に、同じ接続の多くは、繰り返し開閉されることをこれが意味。これは、CPUのパフォーマンスコストです。オープン接続のコストを最小限に抑えるために、ADO.NETは、接続プールとして知られている最適化技術を使用して。最適化技術のJavaは、JDBC接続プールです。

一般的には、データベースにアクセスするJavaアプリケーションのプロセスは以下のとおりです。

  1. データベースドライバをロードします。
  2. データベース接続は、JDBCを介して確立されます。
  3. データベースへのアクセスは、SQL文を実行します。
  4. データベースから切断します。

これは、JDBCマッピングとデータベース接続の共通のTomcat、データベース接続ステップであります

データベースにアクセスするネットFramwork /ネットコアアプリケーションのプロセスは、.NETデータプロバイダによって4つのコアの主題です。

1.Connection:データベース2.Commandへの接続:データソースからデータを読み出すための4.DataAdapterは責任:データの収集とデータベースのための連絡先は、責任データベースが3.DataReaderのコマンドを実行

これは、マッピングデータベース接続Ado.netです

Ado.net:

Ado.netデータベース接続ステップ:

1.新建一个数据库连接字符串
string conStr = “Data Source=.;Initial Catalog=MySchoolDB;Integrated Security=True”;
2.引入命名空间:
using System.Data.SqlClient;
3.创建SqlConnection对象
SqlConnection conn = new SqlConnection(conStr);
4.打开连接:
conn.Open();
5.关闭连接:
conn.Close();
五、使用Command对象的步骤:
1.创建数据库连接
SqlConnection conn = new SqlConnection(conStr);
2.定义sql语句
string sql = “insert into Admin values(‘值’)”;
3.创建SqlCommand对象
SqlCommand cmd = new SqlCommand(conn,sql);
4.执行命令
cmd.ExecuteScalar();

我々はすでに、接続時には、交通瞬間に急増した場合の場合、スレッドは、この時間は、高QPSの高い同時アクセスに対処するには不十分となっている基本的な接続でデータベースへのアクセスのより開かれることを知っています

今回Mircosoftは、データプロバイダーの接続プーリング--Ado.net接続プールが提供するデータベースを作成しました。それは、アプリケーションが完全なプロセス接続を閉じる/設立を完了するたびを避けるために、接続プールで使用される接続を保存することができます。

データプロバイダは、接続要求があるの受信時に接続を確立するプロセスを完了します。

  1. (すなわち、「論理接続」)、および対応する「論理コネクション」の確立「物理接続」を接続プールに新しい接続を確立します 「論理接続」を確立するの設立を添付しなければならない「物理的な接続。」
  2. データプロバイダは、完全な閉鎖手順は「論理接続」に対応する「物理接続」と破壊シャットダウンする添付の「論理接続」を
  3. 「論理接続」)が近い「物理的な接続」、SqlConnection.Open(添付しなければならない破壊が接続データプロバイダを要求していることは、必ずしもデータプロバイダへの接続の完全なプロセスを確立するために完了する必要はありません、単に利用可能な接続プールから削除しますすることができます。
  4. SqlConnection.Close()は接続を閉じるための要求で、データプロバイダは、必ずしも接続を閉じるのフルコースを完了する必要はありません、あなただけのコネクタが接続プールに解放することができます必要があるかもしれません。

今私は、データベース接続の効果の接続プールを使用せずにテストするためのテストコードを書く:私は、WindowsのパフォーマンスカウンタとCPUの消費量を検出しながら、

class Program
{
    static void Main(string[] args)
    {
        SqlConnection con = new SqlConnection("server=.\\sqlexpress;database=zsw;pooling=true;trusted_connection=true;uid=sa;pwd=zsw158991626ZSW;");
        for (int i = 0; i < 10; i++)
        {
            try
            {
                con.Open();
                Console.WriteLine("开始连接数据库" + System.Threading.Thread.CurrentThread.Name);
                System.Threading.Thread.Sleep(1000);
            }
            catch (Exception e) { Console.WriteLine(e.Message); }
            finally
            {
                con.Close();
                System.Threading.Thread.Sleep(1000);
            }
        }
        Console.Read();
    }
}

今回私のコードは、データベース接続プールの上で、私の接続だけが、私たちはConsole.Readkeyを取り除く際により自分のコンピュータに自分のデータ接続は、10を占め、この時点でプール= falseを設定しますSQLServerのパフォーマンステストは開かないが、あなたは、後でオンラインBaiduは接続数を表示しようと行くことができます

しかし!データベースに接続されている。ネットコアは、私は長い文書なしの結果を見つけるデフォルトのオープンデータ接続プール、のようです。

このプールは、だから、それは何ですか?

たびプログラムは、データベースに読み書きするための時間が必要です。Connection.Open()は、データベースに接続できるように、ConnectionStringを使用するデータベースは、プログラムのための接続を確立すると、プログラムがデータベースを更新/クエリにT-SQLステートメントを使用することができた後、開いたままになります。Connection.Close()を実行するとき、データベースは、現在の接続を閉じます。まあ、すべてのルックスはとても整然としたです。

私のプログラムの必要性を開くためにタイミングと(例えばASP.NetやWebサービスなど)近くに接続されていない場合でも、たとえば、HTTPリクエストがサーバーに送信されたときに,,我々は表から*接続を開き、[選択]を使用する必要があるのDataTableを返します。 /クライアント/ブラウザへのDataSet、その後、近くに現在の接続。システム全体のための頻繁な操作ので、すべてのオープン/クローズの接続は間違いなく無駄になること。

ADO.Netチームは、よりよい解決策の方法を提供します。以前に保存した接続時に、次の接続に以前の接続、次の時間が開いている接続にする必要があります。これは、接続プールです。

さて、このプールは、それを操作する方法ですか?

プログラムはConnection.open()、ADO.net裁判官への必要性を実行したときにまず、あなたはFalseを指定した場合、この接続がサポートする接続プール(プールのデフォルトはTrueです)、ADO.netをするために(データベースとの接続の間に作成されます回避の混乱に、データベースに接続されているすべてのは、「接続」の説明)を使用し、その後、プログラムに戻ります。あなたがTrueを指定した場合(「接続」の記述を使用し、すべての接続.NETプログラム)を、ADO.net基づいて行われますConnectStringのは、接続プールを作成し、接続プールへの接続を記入します。ミンプールサイズによって決定される数を埋めるために、接続のプロパティ(デフォルトは0です)。5が指定されている場合、例えば、ADO.netオープンSQLデータベース5との間の時間は、その後、接続プールに格納された接続4は、接続が戻って、接続されています。

プログラムは、Connection.close()のために実行される場合。プーリング接続プールは真、ADO.net現在の接続置けば置くと接続データベースとの間に保持されます。また、接続の寿命を決定しながら、時間がConnection接続寿命を超えて存在する場合0は、無限大を表し、特性(デフォルトは0である)、ADO.net接続は、Connectionに戻すのではなく、保存、データベースへの接続から切断しながら、閉鎖されでプール。

(これは主に、SQLデータベースのクラスタリングに使用され、目的の負荷分散)。プールがFalseを指定すると、データベース間で直接切断。

次いで、時間のConnection.Open()実装次回は、ADO.Net接続が新しいのConnectionStringれたconnectionStringが以前プールが一致している接続に格納されているかどうかを決定します。(ADO.NetのConnectionStringは新しいのConnectionStringが正確に接続文字列に特定の属性をConnectionののConnectionStringも追加余分なスペースに接続プールに保存された一致し、または変更する必要があり、そう言って、バイナリストリームに変わります順序は、ユーザーID、パスワードの認証方法を使用しているのであれば、ADO.Netはこれが新しい接続であると思うし、新しい接続を再作成するようになります、パスワードを変更するあなたは、SQLを使用している場合は、接続につながります認証を統合し、あなたはそれを用いた2つの接続)を保存する必要があります。

ADO.net次いで必要現在の接続プール接続が(別のプログラムによって使用されていない)が使用されてもよいかどうかを決定するために、されていない場合、(デフォルトは100)ADO.net最大プールサイズのConnectionString設定を決定Connectionがあればすることが必要ですすべての接続プールが最大プールサイズに到達していない、ADO.netは、接続を作成するために、再度データベースに接続し、その後接続プログラムに戻ります。

あなたがMaxPoolSizeに達している場合は、ADO.netは再び新しい接続を作成しませんが、待機接続プールは、他のプログラムの接続解除によって占有されている、SqlConnection.ConnectionTimeoutことで、この待ち時間はまた、制限(デフォルトは15秒です)接続プールの数に達している間、15秒以上あれば、SqlConnectionオブジェクトは、SqlConnection.open()メソッドは、タイムアウトエラーをスローした場合ので、時々、一つの可能​​な理由は何もタイムリーConnnection以前近いがないことである(エラーをスローしますされていますMaxPoolSize。)

1が利用可能な場合は接続プールの接続から外し接続は、直接プログラムに戻されていない、ADO.netも(デフォルトはTrueです)ConnectionReset ConnectionStringプロパティをチェックするために、ほとんどの時間接続リセットの必要性を必要とします。プログラム接続から戻る前に、返される接続は、文字列が初期カタログデータベースに指定されていない現在の接続部に接続されている可能性があり、例えば、使用が現在の接続を変更する方法をSqlConnection.ChangeDatabase、修飾されていてもよいからです。現在の接続をリセットする必要があります。しかし、すべての余分なチェックのためには、システム上のオーバーヘッドADO.net接続プールを増加します。

接続プールは、それぞれ独自の接続文字列のために作成されます。あなたがプールを作成すると、接続オブジェクトの複数の最小プールサイズを満たすために作成され、プールに追加されます。プールに追加する必要が接続されているが、(デフォルトは100)最大プールサイズを超えることはできません。接続が閉じているか開いているとき、バックプールにリリース。

概要

場合SqlConnectionオブジェクト要求、オブジェクトを取得するために、プールから利用可能な接続がある場合。接続して利用可能な、それは、関連するトランザクションコンテキストマッチングや任意のトランザクションコンテキストを持つ、使用してはならない、とサーバが有効なリンクを持っています。

接続はこれらの接続要求を満たすために、プールに解放されたときに再配置することで、プロセスを接続プーリング。最大プールサイズに達していると使用可能な接続がない場合、要求はキューに入れられます。その後、再確立プールに(デフォルトは15秒です)タイムアウトに達するまで任意の接続をしようとするプロセス。接続プロセスの前にプールが要求を満たすことができない場合は、例外がスローされます。

コネクションプーリングの良い使用が大幅にアプリケーションのパフォーマンスを向上します。利益よりも逆に、使用している場合、不適切に、そしてより多くの害。一般的には、以下の原則に従ってください:

  1. 接続時間の最新のアプリケーションでは、接続は早い時期にリリースされます。
  2. 接続が閉じられたときに、関連するユーザ定義のトランザクションをオフにします。
  3. 接続プールは、少なくとも1つのオープン接続を持って確保し、維持します。
  4. 細胞の破片を生成しないようにしてください。生成された細胞の破片や多くのデータベースを使用することによって生成された統合セキュリティ・プールの破片を含みます。

JDBC:

Ado.netがとても自然に2を比較した、JDBCを話し、私も最近学んだので、Java言語を来ました

デフォルトのJDBCデータベース接続プール

この方法は、接続プールJDBC APIを提供していません。このようBEAのWebLogicおよびIBMのWebSphereなど、一部の大規模なWebアプリケーションサーバは、接続プールメカニズムを提供しますが、接続プールを使用するためのサードパーティのサポートの特殊なクラスメソッドが存在しなければなりません。

JDBCは、データベース接続プールは、典型的には(WebLogicのは、WebSphere、Tomcatの)実装サーバによって提供される唯一のインタフェースDataSourceが、オープンソースの実装の数が設けられているのjavax.sql.DataSourceを表すために使用されます。

  ①DBCPデータベース接続プール

  ②C3P0データベース接続プール

  データソースは、通常、データ・ソース、接続プーリングおよび二つの部分に接続プール管理を含むと呼ばれ、習慣は、しばしば、接続プールのデータソースと呼ばれます

  アプリケーション全体のニーズは、一つのデータソースに、データベース生成プラントに接続されているデータソースを複数作成することなく、さまざまなデータソースとデータベースに接続されています。

  データベースアクセスの終了後に、プログラムがまだデータベース接続閉じる前と同じである:はconn.close();しかし、コードの上に近いデータベースへの物理接続をしない、それだけでデータベース接続プールに返さデータベース接続のリリースです。

JDBCデータベース接続プールのメカニズム:

データベース接続プールは、データベース接続の配布、管理、リリースする責任があります。初期化時にデータベース接続プール、接続プールへの接続の特定の数を作成し、これらのデータベース接続の数は、データベース接続の最小数を設定するために行われます。彼らは、データベース接続を使用していないかどうか、接続プールは、常に、少なくとも接続の多くの数ので、そこに残ります。データベース接続プールの最大数は、接続の最大数は、接続プール、接続プールへのアプリケーション要求の接続の数がこの限界よりも大きい場合、要求は待ち行列に追加されることにより、占有制限します。接続の最小数とデータベース接続の最大数は、いくつかの要因を考慮するように設定しました:

アプリケーションはデータベース接続が特に大きくない使用している場合、データベース接続リソースの多数が存在することになる場合、1)データベース接続のデータベース接続プールへの接続の最小数は、残る無駄になります。

この番号は、データベース接続要求を超えた場合2)接続の最大数は、データベース・アプリケーションへの接続の最大数は、データベース接続要求は、後後者は、データベースの動作に影響を与えるように、待ち行列に追加されることができるされています。

3)接続に相当する接続の最小数よりも接続の最小数と大きな違いは、接続要求の後より、利益への最初であろうとの接続の最大数新しいデータベース接続を再作成する場合であるが、最小値よりもこれらのより大きな接続数、データベース接続を使用して終了していないが、すぐに解放され、それが再利用または解放アイドルタイムアウトを待ってから、接続プールに配置されます。

今、私たちは、データベースに接続するためにDBCPの方法を使用してみてください

1、最初のMavenプロジェクトを作成し、リソースの新しいファイルdb.propertiesを作成します

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mysql?&useSSL=false&serverTimezone=UTC
jdbc.username=root //用户名
jdbc.password=123456 //密码
initSize=10 //初始化连接数
maxTotal=200 //最大连接数
maxIdle=60 //最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。

図2は、パッケージの依存関係のMavenの導入に続いて

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.19</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-dbcp2</artifactId>
        <version>2.7.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
        <version>2.7.0</version>
    </dependency>

    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
</dependencies>

直接コピーして貼り付け、しかししてくださいノートあなたがしなければならないことを再JDKのデフォルトのバージョン8以上!

3、その後、新しいクラスJdbcUtil

package com.jdbc.util;    
import org.apache.commons.dbcp2.BasicDataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;

/**
 * DBCP的方式链接数据库
 */
public class JdbcUtil {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;
    private static int initSize;
    private static int maxTotal;
    private static  int maxIdle;
    private static BasicDataSource ds;
    static {
        ds = new BasicDataSource();
        Properties cfg=new Properties();
        try { //读取db.properties文件
            InputStream in = JdbcUtil.class
                    .getClassLoader()
                    .getResourceAsStream("db.properties");
            cfg.load(in);
            //初始化参数
            driver=cfg.getProperty("jdbc.driver");
            url=cfg.getProperty("jdbc.url");
            username=cfg.getProperty("jdbc.username");
            password=cfg.getProperty("jdbc.password");
            initSize=Integer.parseInt(cfg.getProperty("initSize"));
            maxTotal=Integer.parseInt(cfg.getProperty("maxTotal"));
            maxIdle=Integer.parseInt(cfg.getProperty("maxIdle"));
            in.close();
            //初始化连接池
            ds.setDriverClassName(driver);
            ds.setUrl(url);
            ds.setUsername(username);
            ds.setPassword(password);
            ds.setInitialSize(initSize);
            ds.setMaxTotal(maxTotal);
            ds.setMaxIdle(maxIdle);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    public static Connection getConnection() {//连接数据库封装类
        try {
            /*
             * getConnection()从连接池中获取的重用
             * 连接,如果连接池满了,则等待。
             * 如果有归还的连接线,则获取重用的连接
             */
            Connection conn = ds.getConnection();
            return conn;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    public static void close(Connection conn) {//关闭数据库的连接方法,封装复杂的关闭过程;
        if(conn!=null) {
            try {
                //将用过的连接归还到连接池
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

4、我々は確認するために、クラスのテストを書きます

package com.jdbc.service;
import com.jdbc.util.JdbcUtil;

import java.sql.Connection;
import java.sql.SQLException;

public class JdbcTest {
    public static void main(String[] args) {
        try {
            for (int i=0;i<1000;i++){
                Thread a= new Thread(new TestThread(),"线程:"+(i+1));
                a.start();
                System.out.println(a.getName()+"已启动");
            }
        }
        catch (Exception ex){
            ex.printStackTrace();
        }
    }
    private static class TestThread implements Runnable{

        private Connection con= JdbcUtil.getConnection();
        @Override
        public void run() {
            try {
                if (con.isClosed()){
                    System.out.println("连接已经关闭");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            finally {
                //JdbcUtil.close(con);
                //System.out.println("\t"+Thread.currentThread().getName()+"已关闭");
            }
        }
    }
}

今すぐテストを実行し、その出力を見つけました

ポートは、スレッドプールの作業を開設し、200を占めているが、私は、接続ポートを解放しませんでしたが、私は接続の最大数は300だったビットdb.propertiesを変更し、今の結果での外観をしましょう

あなたは私達のデータベース接続が与えられている見ることができ、これはなぜですか?ポートは200以上が崩壊する接続されているだけで、私のローカルのMySQL接続ポート200ので。また、一般的なデータベース接続のボトルネックであります

今、私たちは、あなたがある場合でも、千台の接続が迅速に実行され、余分なポートを占有しないことを見ることができ、接続コメントのないコードを閉じます

DBCPの方法は、少なくとも一般的な同時実行外出先で、そのTomcatの中でデータ接続プールまたは必要に応じてを使用して、Tomcatのサーバを使用する方法です!データベース接続プールは、いずれかのアプリケーションサーバと統合利用することができ、アプリケーションは、独立して使用することができます。

概要

JDBC JAVAおよびMicrosoft Ado.netが実際に本質的な違いは、データベースの操作のためのもの、大きさではない、その基本的なパフォーマンスのボトルネックリンクの最大のデータベースは、実際には問題ありか?

その後、データベースのインデックスは、データベースは現在のサブテーブルサブライブラリー、読み込みと書き込みが原因で何であるために分離技術はありますか?そのため、データベース接続プールは、人々が探索するのを待つの将来の操作でパフォーマンスの最適化、データベースの最適化と、より多くの一つであります

現在アリババドルイドなど、MicrosoftのORMも早く開いたインターネットの将来は、パフォーマンスのボトルネックは、従来のリレーショナルデータベースとの状況となっているではありませんマークデータベース接続プーリング用に最適化されている、最も需要良い結果です

将来のNoSQL人気の介入は、その高い同時実行、より良いので大規模なインターネットプロジェクトのタスクを引き受け!

Ado.netおよびJDBC私はパフォーマンスを比較するために時間がかからなかったため、実際には、私はまた、JavaのようなC#のように、これは優れた言語が互いに学びである、とあなたはどのように書き込みに理解するために開始した場合、我々は、学習アルゴリズムとして、コードを書きます私は良いコードは、あなたが言語のパフォーマンス上の利点を気にしないだろうと信じています。

この記事では、を参照します。

https://blog.csdn.net/huwei2003/article/details/71459198

https://blog.csdn.net/hliq5399/article/details/73292023

https://blog.csdn.net/weixin_40751299/article/details/81609332

https://www.cnblogs.com/justdoitba/p/8087984.html

https://www.cnblogs.com/albertrui/p/8421791.html

https://blog.csdn.net/L_it123/article/details/88205528

記事の大物以上のおかげで、私はこの記事を書くための時間を節約することができます。

おすすめ

転載: www.cnblogs.com/sandaman2019/p/12558313.html