


下載本文檔
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、相關技術: 連接池 引用記數 多線程 C#.Net Java 適宜人群 數據庫應用程序程序員 系統分析員 模塊設計師 有一定功底的程序員 目錄 引言 數據庫連接池 <Connection Pool )的工作原理 連接池關鍵問題分析 并發問題 事務處理 連接池的分配與釋放 連接池的配置與維護 關鍵議題 引用記數 如何實現事務處理 管理連接池 結合代碼說明 構造方法 啟動服務 StartService 停止服務 StopService 申請 GetConnectionFormPool 釋放 DisposeConnection 如何更新屬性 如何確定連接是否失效 使用線程管理連接池 threa
2、dCreate threadCheck 其他 引言一般的數據庫應用程序大致都遵循下面的步驟 初始化程序用戶在 UI 上輸入操作 由用戶操作產生數據庫操作 將數據庫操作遞交到數據庫服務器 ( 重復 24> 關閉應用程序而本文則著重講解上面第4步驟 .在著一步驟中我們經常是 ,打開數據庫連接操作數據庫最后關閉數據庫 .在服務器端程序設計上與數據庫的操作顯得十分重要,因為你要處理的數據操作十分巨大.如果頻繁創建數據庫連接頻繁關閉數據庫連接則會引起效率低下甚至引發程序崩潰 .也許我們可以有另一種操作數據庫的形式,我們可以在程序運行時打開一個數據庫連接讓這個連接永久存在直到程序' 死亡 &
3、#39;,那么這樣做也有不安全隱患,我們知道一個對象存在時間越長或被使用次數越多則它表現的越不穩定,著不穩定因素是因為對象內部可能存在的潛在設計問題產生 , 對于數據庫連接對象道理也一樣.我們不能保證一個 Connection 對象里面能一點問題不存在 .所以我們也不敢長時間將它長時間占用內存.既然有這么多的問題由此我們需要一個能幫我們維護數據庫連接的東西 - 它就是連接池 網上有很多的連接池例子,但是多數都是簡單的例子 ,或者介紹比較復雜的連接池原理,沒有一個比較完整介紹和實現連接池的例子.這里就介紹你如何自己制作一個連接池.對于共享資源,有一個很著名的設計模式:資源池Resource Po
4、ol)。該模式正是為了解決資源的頻繁分配、釋放所造成的問題。為解決我們的問題,可以采用數據庫連接池技 術。數據庫連接池的基本思想就是為數據庫連接建立一個“緩沖池”。預先在緩沖池中放 入一定數量的連接,當需要建立數據庫連接時,只需從“緩沖池”中取出一個,使用完畢 之后再放回去。我們可以通過設定連接池最大連接數來防止系統無盡的與數據庫連接。更 為重要的是我們可以通過連接池的管理機制監視數據庫的連接的數量、使用情況,為系統 開發、測試及性能調整提供依據。連接池的基本工作原理見下圖。數據庫連接池 <Connection Pool )的工作原理 連接池關鍵問題分析1、并發問題 為了使連接管理服務具
5、有最大的通用性,必須考慮多線程環境,即并發問題。這個問題相對比較好解決,因為各個語言自身提供了對并發管理的支持像java,c#等等,使用synchronized(java>lock(C#> 關鍵字即可確保線程是同步的。使用方法可以參考,相關文 獻。2、事務處理我們知道,事務具有原子性,此時要求對數據庫的操作符合“ALL-ALL-NOTHING ”原則,即對于一組 SQL 語句要么全做,要么全不做。我們知道當2個線程公用一個連接 Connection 對象,而且各自都有自己的事務要處理 時候,對于連接池是一個很頭疼的問題,因為即使 Connection 類提供了相應的事務支持, 可是
6、我們仍然不能確定那個數據庫操作是對應那個事務的,這是因為我們有2個線程都在 進行事務操作而引起的。為此我們可以使用每一個事務獨占一個連接來實現,雖然這種方 法有點浪費連接池資源但是可以大大降低事務管理的復雜性。3、連接池的分配與釋放 連接池的分配與釋放,對系統的性能有很大的影響。合理的分配與釋放,可以提高連接的復用度,從而降低建立新連接的開銷,同時還可以加快用戶的訪問速度。對于連接的管理可使用一個List。即把已經創建的連接都放入List中去統一管理。每當用戶請求一個連接時,系統檢查這個 List 中有沒有可以分配的連接。如果有就把那個最 合適的連接分配給他 <如何能找到最合適的連接文章
7、將在關鍵議題中指出);如果沒有就 拋出一個異常給用戶, List 中連接是否可以被分配由一個線程來專門管理捎后我會介紹這 個線程的具體實現。4、連接池的配置與維護連接池中到底應該放置多少連接,才能使系統的性能最佳?系統可采取設置最小連接 數 minConnection )和最大連接數 maxConnection )等參數來控制連接池中的連接。比方 說,最小連接數是系統啟動時連接池所創建的連接數。如果創建過多,則系統啟動就慢, 但創建后系統的響應速度會很快;如果創建過少,則系統啟動的很快,響應起來卻慢。這 樣,可以在開發時,設置較小的最小連接數,開發起來會快,而在系統實際使用時設置較 大的,因為
8、這樣對訪問客戶來說速度會快些。最大連接數是連接池中允許連接的最大數 目,具體設置多少,要看系統的訪問量,可通過軟件需求上得到。如何確保連接池中的最小連接數呢?有動態和靜態兩種策略。動態即每隔一定時間就 對連接池進行檢測,如果發現連接數量小于最小連接數,則補充相應數量的新連接,以保證連接池的正常運轉。靜態是發現空閑連接不夠時再去檢查。關鍵議題引用記數 在分配、釋放策略對于有效復用連接非常重要,我們采用的方法也是采用了一個很有 名的設計模式: Reference Counting 引用記數)。該模式在復用資源方面用的非常廣泛, 我們把該方法運用到對于連接的分配釋放上。每一個數據庫連接,保留一個引用
9、記數,用 來記錄該連接的使用者的個數。具體的實現上,我們對 Connection 類進行進一步包裝來實 現引用記數。被包裝的Connection類我們提供2個方法來實現引用記數的操作,一個是Repeat被分配出去)Remove被釋放回來);然后利用RepeatNow屬性來確定當前被引用多少,具體是哪個用戶引用了該連接將在連接池中登記;最后提供IsRepeat屬性來確定該連接是否可以使用引用記數技術。一旦一個連接被分配出去,那么就會對該連接的申請者 進行登記,并且增加引用記數,當被釋放回來時候就刪除他已經登記的信息,同時減少一 次引用記數。這樣做有一個很大的好處,使得我們可以高效的使用連接,因為
10、一旦所有連接都被分 配出去,我們就可以根據相應的策略從使用池中挑選出一個已經正在使用的連接用來復 用,而不是隨意拿出一個連接去復用。策略可以根據需要去選擇,我們有4策略可是使 用:1 .Co nn Level_ReadO nly 獨占方式使用空閑的實際連接分配連接資源,并且在該資源釋放回之前,該資源在連接池中將 不能將其引用分配給其他申請者。如果連接池中所有實際連接資源都已經分配出去,那么 即使連接池可以在分配引用資源在該模式下連接遲將不會分配連接資源,連接池會產生一 個異常,標志連接池資源耗盡。例:假如一個實際連接可以被分配 5 次,那么使用該模式申請連接的話您將損失 4 個 可分配的連接,
11、只將得到一個連接資源。直至該資源被釋放回連接池,連接池才繼續分配它剩余的 4 次機會。當你在使用連接時可能應用到事務時,可以使用該模式的連接,以確定在事務進行期 間您可以對該連接具有獨享權限,以避免各個數據庫操作訪問的干擾。2 .ConnLevel_High 優先級 -高使用空閑的實際連接分配連接資源,并且在該資源釋放回之前,該資源在連接池中將 可能將其引用分配給其他申請者。*注意:此級別不保證在分配該資源后,仍然保持獨立占有連接資源,若想獨立占有資源請使用 ReadOnely, 因為當連接池達到某一時機時該資源 將被重復分配 引用記數)然而這個時機是不可預測的。如果您申請的連接會用于事務處
12、理您可以使用 ConnLevel_ReadOnly 級別。3 .ConnLevel_None 優先級-中適當應用引用記數技術分配連接資源。在該模式下,連接池內部會按照實際連接已經使用次數排序(多-少,然后在結果中選取1/3 位置的連接資源返回。與優先級-高相同該模式也不具備保持獨立占有連接資源的特性。如果您申請的連接會用于事務處理您可以使用 ConnLevel_ReadOnly 級別。4 .ConnLevel_Bottom優先級-底盡可能使用引用記數技術分配連接。在該模式下,連接池內部會按照實際連接已經使用次 數排序 (多 -少,然后在結果中選取被使用最多的返回。該模式適合處理較為不重要的連
13、接資源請求。與優先級 -高相同該模式也不具備保持獨立占有連接資源的特性。如果您申請 的連接會用于事務處理您可以使用 ConnLevel_ReadOnly 級別。以上 4 條策略選自 datebasepool_SDKdatebasepool 是本文所開發的最終產物) 如何實現事務處理前面談到的都是關于使用數據庫連接進行普通的數據庫訪問。對于事務處理,情況就 變得比較復雜。因為事務本身要求原子性的保證,此時就要求對于數據庫的操作符合"All-All-Nothing" 原則,即要么全部完成,要么什么都不做。如果簡單的采用上述的連接復用的 策略,就會發生問題,因為沒有辦法控制屬于同
14、一個事務的多個數據庫操作方法的動作, 可能這些數據庫操作是在多個連接上進行的,并且這些連接可能被其他非事務方法復用。Connection 本身具有提供了對于事務的支持,具體實現方法請參看Connection 的msd n,顯式的調用 commit或者rollback方法來實現。但是要安全、高效的進行Conn ection進行復用 , 就必須提供相應的 事務支持 機制。 我們采用 的方 法 是:用 戶 以 ConnLevel_ReadOnly 模式申請一個連接之后該連接就由該申請者獨自享有該連接,具體事 務操作由用戶自行設計編寫,連接池只提供用戶獨自占有。管理連接池 在上文中我們說過這個連接池內
15、部連接管理使用的是獨立的線程來工作threadCreate和threadCheck)threadCreate線程負責創建連接,threadCheck線程負責檢查每個連接是否達到自己的壽命,標志連接壽命的條件是被引用的次數超過它最大被引用次數,或者達到 最大生存時間。這些參數都由 ConnStruct 類管理, ConnStruct 類是包裝連接的類,下面定 義的就是連接池使用到的屬性變量(C#代碼/屬性private int _realFormPool 。 /連接池中存在的實際連接數(包含失效的連接 private int _potentRealFormPool 。 /連接池中存在的實際連接數
16、(有效的實際連接 private int _spareRealFormPool 。 /空閑的實際連接 private int _useRealFormPool 。 /已分配的實際連接private int _readOnlyFormPool 。 /連接池已經分配多少只讀連接private int _useFormPool 。 /已經分配出去的連接數 private int _spareFormPool 。 /目前可以提供的連接數 private int _maxConnection 。 /最大連接數,最大可以創建的連接數目 private int _minConnection 。 /最小連接數
17、 private int _seepConnection 。 /每次創建連接的連接數private int _keepRealConnection。 /保留的實際空閑連接,以攻可能出現的ReadOnly 使用,當空閑連接不足該數值時,連接池將創建seepCo nn ection個連接private int _exist = 20 。 /每個連接生存期限 20 分鐘private int _maxRepeatDegree = 5。 /可以被重復使用次數 引用記數),當連接被重復 分配該值所表示的次數時,該連接將不能被分配出去/當連接池的連接被分配盡時,連接池會在已經分配出去的連接中,重復分配連接
18、引用記數)。來緩解連接池壓力private DateTime _startTime 。 /服務啟動時間private string _connString = null 。 /連接字符串private ConnTypeEnum _connType 。 / 連接池連接類型private PoolState _ps。/ 連接池狀態/ 內部對象private ArrayList al_All = new ArrayList(> 。 /實際連接private Hashtable hs_UseConn = new Hashtable(> 。 / 正在使用的連接private System.T
19、imers.Timer time 。 / 監視器記時器private Thread threadCreate。 / 創建線程private bool isThreadCheckRun = false 。Java 版本/ 屬性private int _RealFormPool 。 / 連接池中存在的實際連接數 (包含失效的連接 >private int _PotentRealFormPool 。 /連接池中存在的實際連接數 ( 有效的實際連接 >private int _SpareRealFormPool 。 / 空閑的實際連接private int _UseRealFormPool
20、 。 / 已分配的實際連接private int _ReadOnlyFormPool 。 / 連接池已經分配多少只讀連接private int _UseFormPool 。 /已經分配出去的連接數private int _SpareFormPool 。 / 目前可以提供的連接數private int _MaxConnection 。 / 最大連接數,最大可以創建的連接數目private int _MinConnection 。 / 最小連接數private int _SeepConnection 。 / 每次創建連接的連接數private int _KeepRealConnection 。 /
21、 保留的實際空閑連接,以攻可能出現的ReadOnly 使用,當空閑連接不足該數值時,連接池將創建 seepConnection 個連接private int _Exist = 20 。 / 每個連接生存期限 20 分鐘private String _userID="" 。private String _password="" 。/ 可以被重復使用次數 <引用記數),當連接被重復分配該值所表示的次數時,該連接將 不能被分配出去/ 當連接池的連接被分配盡時,連接池會在已經分配出去的連接中,重復分配連接<引用記數)。來緩解連接池壓力private
22、int _MaxRepeatDegree = 5 。private Date _StartTime 。 / 服務啟動時間private String _ConnString = null 。 / 連接字符串private String _DriveString = null 。 / 驅動字符串private int _PoolState 。 /連接池狀態/ 內部對象private ArrayList al_All = new ArrayList(> 。 / 實際連接private Hashtable hs_UseConn = new Hashtable(> 。 / 正在使用的連接p
23、rivate CreateThreadProcess threadCreate。private CheckThreadProcess threadCheck 。當用戶調用連接池的 StartService 方法時,在 StartService 方法中會通知 threadCreate 線 程創 建靜態連接 ,然后將這 些靜態連接 加入到 List , 同時 啟 動 threadCheck 線程 , threadCheck 線程負責檢測 List 中的最小空閑連接是否少于連接池配置的最少空閑連接數, 當條件為真時 threadCheck 線程會負責再次喚醒 threadCreate 線程同時給 t
24、hreadCreate 線程 傳遞這次要創建的連接個數。對于threadCreate線程有2種工作模式,模式0為初始化創建模式,該模式會創建連 接遲池配置的最小連接數目;模式1即每隔一定時間就對連接池進行檢測,如果發現連接 數量小于最小連接數,則補充相應數量的新連接時的工作模式。申請連接,當用戶申請連接時必須指定一個發起者和一個申請優先級別,優先級由 ConnLevel_* 系列指定。一旦用戶從連接池中申請到一個連接時就將申請到的連接引用和申 請者,同時加入到 HashTable來注冊到連接池。釋放連接,將注冊的用戶刪除。下面是代碼說明共有Java和C#2個版本,2版本可能捎有不同因為各個語言
25、有自己的特點Java版本的構造方法public ConnectionPool(> .InitConnectionPool("", "", 200, 30, 10, 5> 。public ConnectionPool(String connectionString, String driveString> .InitConnectionPool(connectionString, driveString, 200, 30, 10, 5> 。public ConnectionPool(String connectionString,
26、String driveString, int maxConnection, int minConnection> .InitConnectionPool(connectionString, driveString, maxConnection, minConnection, 10, 5>。public ConnectionPool(String connectionString, String driveString, int maxConnection, int minConnection, int seepConnection, int keepRealConnection&
27、gt; .InitConnectionPool(connectionString, driveString, maxConnection, minConnection, seepConnection, keepRealConnection>。C#版本的構造方法public ConnectionPool(string connectionString>. InitConnectionPool(connectionString, ConnTypeEnum.Odbc, 200, 30, 10, 5, 5> 。 public ConnectionPool(string connect
28、ionString, ConnTypeEnum cte>. InitConnectionPool(connectionString, cte, 200, 30, 10, 5, 5> 。 public ConnectionPool(string connectionString, ConnTypeEnum cte, int maxConnection, int minConnection>. InitConnectionPool(connectionString, cte, maxConnection, minConnection, 10, 5, 5>。 public C
29、onnectionPool(string connectionString, ConnTypeEnum cte, int maxConnection, int minConnection, int seepConnection, int keepConnection>.InitConnectionPool(connectionString, cte, maxConnection, minConnection,seepConnection, keepConnection, 5> 。 public ConnectionPool(string connectionString, Conn
30、TypeEnum cte, int maxConnection, int minConnection, int seepConnection, int keepConnection, int keepRealConnection>.InitConnectionPool(connectionString, cte, maxConnection, minConnection,seepConnection, keepConnection, keepRealConnection> 。 上面2個版本的構造方法都調用 InitConnectionPool 方法,下面是 InitConnecti
31、onPool 方法 實現 (C#>/*/ <summary>/ 初始化函數/ </summary>protected void InitConnectionPool(string connectionString, ConnTypeEnum cte, int maxConnection, int minConnection, int seepConnection, int keepConnection, int keepRealConnection>.if (cte = ConnTypeEnum.None>throw new ConnTypeExecp
32、tion(> 。 /參數不能是 None_ps = PoolState.UnInitialize 。this._connString = connectionString 。this._connType = cte 。this._minConnection = minConnection 。this._seepConnection = seepConnection 。this._keepRealConnection = keepRealConnection 。this._maxConnection = maxConnection 。this.time = new System.Timer
33、s.Timer(500> 。this.time.Stop(> 。this.time.Elapsed += new System.Timers.ElapsedEventHandler(time_Elapsed> 。 this.threadCreate = new Thread(new ThreadStart(createThreadProcess>> 。在 InitConnectionPool 方法中我們定義了連接池要連接的數據庫類型 ConnTypeEnum cte,和連接字符串 string connectionString等類型,在方法最后注冊了Timer類的
34、Elapsed事件,在 C#版中Timer類就充當threadCheck線程,而 Elapsed事件就是線程 threadCheck的 執行方法體。因為剛剛初始化連接池對象故 threadCheck 線程不需要運行所以在 InitConnectionPool 方法中將 Timer 關閉。下面是 java 實現:private void InitConnectionPool(String connectionString, String driveString, int maxConnection, int minConnection, int seepConnection, int keepR
35、ealConnection> .this._PoolState = PoolState_UnInitialize 。this._ConnString = connectionString 。this._DriveString = driveString 。this._MinConnection = minConnection 。this._SeepConnection = seepConnection。this._KeepRealConnection = keepRealConnection 。this._MaxConnection = maxConnection 。this.threa
36、dCheck = new CheckThreadProcess(> 。this.threadCheck.setDaemon(true> 。this.threadCreate = new CreateThreadProcess(>。this.threadCreate.setDaemon(true> 。this.threadCheck.start(> 。while(threadCheck.getState(>!=Thread.State.WAITING>.因為 Java 中的 Timer 類需要 AWT 的 GUI 線程組建支持,總不能在我們的連接池中開
37、辟一個 Form 出來把,因此在 Java 版本中使用線程來實現 Timer ,在 Java 版本中 threadCheck 一開始就被啟動,然后又等待 threadCheck 線程自己被阻塞又是為什么呢,這 樣做是為了實現 C#版本中stop方法<因為個人原因這個連接池最初是由C#.Net2.0開發而成的故而在Java中可能存在許多設計不合理)。由上面代碼可以看出一旦連接池被創建出來以后就已經運行了一個threadCheck 線程(對于 Java 版>,而這個線程將立刻進入WAITING 等待狀態。啟動服務 StartService/*/ <summary>/ 啟動服
38、務,線程安全/ </summary>public void StartServices(>.lock (this>.createThreadMode = 0 。 / 工作模式 0 createThreadProcessRun = true。 createThreadProcessTemp = _minConnection 。 if (_ps = PoolState.UnInitialize>threadCreate.Start(> 。else if (_ps = PoolState.Stop> threadCreate.Interrupt(> 。
39、elsethrow new PoolNotStopException(> 。 /服務已經運行或者未完全結束 time.Start(> 。 createThreadMode是設置 threadCreate的工作模式為0創建模式,前面我們說過 threadCreate有2種工作模式,如果忘記了就回頭去看看把。createThreadProcessTemp是 threadCreate 工作需要的參數變量threadCreate 會在 0 或者1 這兩種工作模式下用到這個臨時變量該變量作用就是告訴threadCreate 要創建多少個連接,下面的一組 if else 是為了將 thread
40、Create 線程運行起來 _ps 是表示當前連接池狀態,下面是_ps的定義,在 Java版本中PoolState只是一組 public static fin al i nt故在這里不 在將源碼放出。在 StartServices 最后我們啟動了 time 也就是 threadCheck 線程。/ 連接池狀態public enum PoolState.UnInitialize,/ 剛剛創建的對象,表示該對象未被調用過 StartSeivice 方法。 Initialize,/ 初始化中,該狀態下服務正在按照參數初始化連接池。Ru n,運行中Stop/停止狀態PoolState 定義Java 版
41、本/* */* 啟動連接池服務* throws PoolNotStopException 服務已經運行或者未完全結束*/public void StartServices(> throws PoolNotStopException . synchronized (this> .threadCreate.createThreadMode = 0 。 /工作模式 0 threadCreate.createThreadProcessRun = true。 threadCreate.createThreadProcessTemp = _MinConnection 。 if (_PoolSt
42、ate = PoolState_UnInitialize>threadCreate.start(> 。else if (_PoolState = PoolState_Stop> threadCerrupt(> 。elsethrow new PoolNotStopException(> 。 / 服務已經運行或者未完全結束 threadCheck.StartTimer(> 。threadCerrupt(> 。 / 開始運行停止服務 StopService/*/ <summary>/ 停止服務,線程安全/ <
43、;/summary>public void StopServices(>. StopServices(false> 。 /*/ <summary>/ 停止服務,線程安全/ <param name="needs"> 是否必須退出;如果指定為false 與 StartServices(> 功能相同,如果指定為true。將未收回的連接資源關閉,這將是危險的。認為可能你的程序正在使用 此資源。 </param>/ </summary>public void StopServices(bool needs>
44、.lock (this>.if (_ps = PoolState.Run>.lock (hs_UseConn>. if (needs = true>/ 必須退出 hs_UseConn.Clear(> 。else if (hs_UseConn.Count != 0>throw new ResCallBackException(> 。 / 連接池資源未全部回收time.Stop(> 。while (isThreadCheckRun> . / 等待 timer 事件結束 createThreadProcessRun = false。while (
45、threadCreate.ThreadState != ThreadState.WaitSleepJoin> . / 等待可能存在 的創建線程結束lock (al_All>.for (int i = 0 。 i < al_All.Count 。 i+>(ConnStruct>al_Alli>.Dispose(> 。al_All.Clear(> 。_ps = PoolState.Stop 。elsethrow new PoolNotRunException(> 。 / 服務未啟動UpdateAttribute(> 。 / 更新屬性在這里
46、我們使用了 2 層鎖第一層鎖我們是為了保證同一時間只能有一個線程調用這個 方法,而 lock (hs_UseConn> 則是為了保護 hs_UseConn 的唯一訪問 hs_UseConn 存放的就是 申請連接時注冊信息, needs 是將未收回的連接資源也關閉,這將是危險的。認為可能你的 程序正在使用此資源。if (hs_UseConn.Count != 0>throw new ResCallBackException(> 。 / 連接池資源未全部回收。這段代碼是表示如果用戶試圖在連接沒有全部釋放回來時候將會引發異常,同時執行 該方法的必要條件是連接池必須處在 PoolSt
47、ate_Run 狀態。time.Stop(> 。是停止檢測線程的運行 ,while (isThreadCheckRun> . 那為什么要使用這 個空循環等待timer的結束呢?原因是 Timer類的運行基理,在 C#下Timer觸發的事件是 不同于VE的,在.Net里無論Timer事件處理過程的執行時間是否超過它觸發時間間隔在 Timer 里總會在指定時間被調用,也就是說如果觸發間隔卻是 100 毫秒,然而我們的處理 過程用了 500 毫秒來運行代碼。這樣的話下一個事件的觸發將在我們這個事件還沒有結束 時又進行了,如此一來起不是災難的!對于接下來我們還要等待可能存在的 thread
48、Create 線程結束,不過在等待它結束時先 給他發送一個暫停信號,這個信號由 createThreadProcessRun 變量傳遞進去。也許有人回問 為什么不使用join來阻止threadCreate的運行,原因是這樣的,假如threadCreate打算創建minConnection 個連接,然而恰恰在創建到 minConnection - n 個時候我停止也連接 池,如果在這里使用 join 的話我們將不確定下次恢復運行時候究竟要創建多少個連接,最 好的解決辦法就是叫線程自己找一個安全的地方把自己 join。在下面的代碼就是把每一個連接分別銷毀掉并且在連接池中將它刪除掉。有人說,那 你只
49、是刪除了你內部的引用,的確我們只刪除了內部的引用,因為銷毀只是形式的銷毀 在.net上我們不能控制內存去銷毀一個對象,只能叫GC幫忙來清理它。在程序段的最后我 們使用私有的 UpdateAttribute 方法來更新屬性字段。 下面是 Java 版本的代碼/* */* 停止服務,線程安全* throws ResCallBackException 資源未全部回首* throws PoolNotRunException 服務沒有運行*/public void StopServices(> throws ResCallBackException, PoolNotRunException . S
50、topServices(false> 。/* */* 停止服務,線程安全* param needs boolean 是否必須退出;如果指定為 false 與 StartServices(> 功能相同,如 果指定為true。將未收回的連接資源關閉,這將是危險的。認為可能你的程序正在使用此 資源。* throws ResCallBackException 服務未啟動* throws PoolNotRunException 服務沒有運行*/public void StopServices(boolean needs> throws PoolNotRunException, ResC
51、allBackException .synchronized (this> .if (_PoolState = PoolState_Run> .synchronized (hs_UseConn> . if (needs = true> / 必須退出 hs_UseConn.clear(> 。elseif (hs_UseConn.size(> != 0> throw new ResCallBackException(> 。 / 連接池資源未全部回收 threadCheck.StopTimer(> 。 while (threadCreate.ge
52、tState(>!=Thread.State.WAITING> ./ 等待 threadCreate 事件結束threadCreate.createThreadProcessRun = false。while (threadCreate.getState(> != Thread.State.WAITING> ./等待可能存在的創建線程結束synchronized (al_All> .for (int i = 0 。 i < al_All.size(> 。 i+> (ConnStruct> al_All.get(i>>.Dispo
53、se(> 。al_All.clear(> 。_PoolState = PoolState_Stop。 else throw new PoolNotRunException(> 。 /服務未啟動UpdateAttribute(> 。 / 更新屬性申請 GetConnectionFormPool/*/ <summary>/ 在連接池中申請一個連接,使用 None 級別,線程安全/ </summary>/ <param name="gui"> 發起者 </param>/ <returns> 返回申
54、請到的連接 </returns>public DbConnection GetConnectionFormPool(object key>. return GetConnectionFormPool(key, ConnLevel.None> 。 /*/ <summary>/ 在連接池中申請一個連接,線程安全/ </summary>/ <param name="key"> 申請者 </param>/ <param name="cl"> 申請的連接級別 </param&
55、gt;/ <returns> 返回申請到的連接 </returns>public DbConnection GetConnectionFormPool(object key, ConnLevel cl>.lock (this>.if (_ps != PoolState.Run>throw new StateException(> 。/ 服務狀態錯誤if (hs_UseConn.Count = MaxConnectionFormPool>throw new PoolFullException(> 。/ 連接池已經飽和,不能提供連接if
56、(hs_UseConn.ContainsKey(key>>throw new KeyExecption(> 。/ 一個 key 對象只能申請一個連接if (cl = ConnLevel.ReadOnly>return GetConnectionFormPool_ReadOnly(key> 。 /ReadOnly 級別else if (cl = ConnLevel.High>return GetConnectionFormPool_High(key> 。 /High 級別else if (cl = ConnLevel.None>return Get
57、ConnectionFormPool_None(key> 。 /None 級別 elsereturn GetConnectionFormPool_Bottom(key> 。 /Bottom 級別 在向連接池申請一個連接資源時我們必須指定一個申請者,同時可以指定一個級別參 數最后會根據不同的級別調用不同的策略,這些策略是在上面介紹過的 4 鐘策略,下面不 做過多的介紹。<Java版本不在放出原因代碼與C#完全相同)下面將逐一放出4種策略的完整代碼不做過多解釋,其功能以在前文介紹過/*/ <summary>/ 申請一個連接資源,只讀方式,線程安全/ </summ
58、ary>/ <param name="key"> 申請者 </param>/ <returns> 申請到的連接對象 </returns> protected DbConnection GetConnectionFormPool_ReadOnly(object key>.ConnStruct cs = null 。for (int i = 0 。 i < al_All.Count 。 i+>.cs = (ConnStruct>al_Alli 。if (cs.Enable = false | cs.Allot = false | cs.UseDegree = _maxRepeatDegree | cs.IsUse = true>continue 。return GetConnectionFormPool_Return(key, cs, ConnLevel.ReadOnly> 。 / 返回得到 的連接return GetConnectionFormPool_Return(key, null, Conn
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 基坑邊坡網噴混凝土支護施工方案
- Brand KPIs for hotels:Sheraton in the United Kingdom-英文培訓課件2025.5
- 江蘇省南京市江寧區2023-2024學年高二下學期化學期末(含答案)
- 汽車傳感器與檢測技術電子教案:翼片式空氣流量傳感器
- 某公司炭素廠應急預案措施匯編
- 物理中考一輪復習教案 十一講 物質的質量 密度
- 從我做起活動方案
- 倉鼠商人活動方案
- 代寫活動策劃方案
- 代言人創意活動方案
- 吉林鄉土地理知識要點(試卷)
- 保險公司增額終身壽主講課件
- 光學分析導論思政
- 高考前在學校高三班主任對學生的最后一課教育課件
- (2024年)管理體系文件ISO13485
- 無人機航空攝影測量在地形測繪中的應用
- 《天津市建筑節能設計專篇》(公共建筑、居住建筑)
- (新版)煙草制品購銷員(三級)理論知識考試復習題庫大全-下(多選、判斷題匯總)
- 國家職業技術技能標準 6-18-01-01 車工 人社廳發2018145號
- 小兒急乳蛾的護理查房
- 高考英語口語考試短文
評論
0/150
提交評論