天天看點

基于Oracle plsql的多線程程式設計架構 (附存儲過程)

作者介紹

馮守東,北京科訊華通科技發展有限公司進階項目經理。超12年oracle開發及管理經驗,多年營運商和政府企業級系統運維經驗,曾獲得東軟最佳設計方案獎。熟悉weblogic、tuxedo、ibm was等相關中間件運維。熟悉mysql、db2、informix等其他開源或商業資料,以及openstack、hadoop相關生态系統、網站架構設計等。

 引言  

1 文檔編制目的

在日常程式設計範圍内有很多大計算量的存儲過程,在業務系統中使用java實作多線程往往會有參與計算的任務不能均勻配置設定、不能完全發揮資料庫伺服器的高端性能,代碼實作起來門檻較高,比較麻煩。是以,本文檔将通過diy方式介紹如何在oracle資料庫伺服器實作存儲過程的并行處理。

2 背景

有一個很大的計算過程,參與計算的對象非常多。例如資料固化、應收核定等。

要用pl/sql逐行處理,當然這這樣做會有大量的讀取和dml操作。

我們使用一台多cpu的資料庫伺服器,并且有大量磁盤空間。

我們發現作業系統/sql并不是非常容易擴充的,它隻使用了1個cpu,并沒有利用整個機器。

由于我們使用固有的單線程程式來處理資料,oracle并行查詢不可用!

“一個人的活多個人做”并行處理,将固有的任務/資料分解成n個不重疊的組,同時開始pl/sql子程式n個拷貝。

3 範圍

本文檔适用于所有使用oracle 10g的項目,系統吞吐量大,有一定執行時間限制的應用場合。

4 詞彙表

詞彙名稱

詞彙含義

備注

dbms_scheduler

oracle任務排程器

隻有oracle 10g支援新特性

read lock

oracle行排他鎖

oracle 任何版本

autonomous transactions

oracle自治事務

dynamic sql

oracle 動态sql

總體架構設計

原則:

提供一個脫離業務、通用性強的功能元件。

易于複用,代碼修改少,可配置滿足不同要求。

對控制重複執行有所考慮。

元件提供人性化的客戶互動界面,解決進度情況展示的問題。

能有一個實作和效率之間的平衡。

方法:

此元件中的并行執行遵循了幾乎相同的邏輯。通常可以将某個大“任務”劃分為較小的部分,并且并發地執行各個部分。例如,如果需要計算一大批結果并把資料儲存到資料庫中,那麼完全可以建立4 個或更多并行會話(p001~p004)來一起執行存儲過程,任務的分派有一個任務分派器來做,分派器可以按照每個程序的負載情況均勻的分派任務。每個會話分别調用預定義的業務過程來執行分派器分派的任務。當需要送出處理結果的時候,可以在每個業務過程内進行儲存。

此元件作為一種實作架構,可以使一些要求吞吐量大、執行效率高的的操作得到大幅改善,使其能夠呈數量級提高。由于此架構對系統資源要求較高,通常情況下應該在非高峰期而且有足夠資源的情況下之用。

2 系統整體架構

基于Oracle plsql的多線程程式設計架構 (附存儲過程)

3 系統級元件

dbms_scheduler是oracle 10g中新增的一個包,與老版本的dbms_job包相比,dbms_scheduler有很多新特性。oracle 10g引入dbms_scheduler來替代先前的dbms_job,在功能方面,它比dbms_job提供了更強大的功能和更靈活的機制。

dbms_job這個程式包存在的問題是它隻能夠處理 pl/sql 代碼段,即僅能處理匿名程式塊和存儲程式單元。它不能在資料庫外部處理作業系統指令檔案或可執行檔案中的任何東西。 

為此,您将不得不求助于作業系統排程實用工具。另外dbms_job所生成任務程序一旦生成就在資料庫中一直有效,不能在任務結束後自動終止。

dbms_schedule是直接在資料庫内部的一個作業排程實用程式,強大到足夠處理所有類型的作業,而不隻是 pl/sql 代碼段。它可以在處理任務執行結束後自動終止。最好的一點是它是資料庫自帶的,無需任何額外的成本,這樣我們在實作上直接使用即可。

4 流程圖各部分說明

前台使用者:主要是進行程式排程,主要是任務是把我程式執行時機。

任務清單:通過一個普通表實作,該表中主要包括了業務過程執行過程中所需要的入參,參數的形式為‘|’分隔的字元串。同時附加了異常及進度資訊。該表是由程式開發人員根據具體的業務定義結構并生成入參資料。

程序控制:根據系統參數或業務參數調用dbms_scheduler生成對應個數的服務程序。依據目前程序執行情況,控制任務的重複執行。當出現緊急情況時終止所有服務程序。

任務讀取:通過oracle的自制事務及鎖特性,實作任務讀取的一緻性,即每次服務程序處理一行任務資料的時候,不被其它的服務程序重複讀取。

業務過程:該部分同樣由程式開發人員根據具體業務類型開發存儲過程。該過程根據傳入的過程名稱和參數個數動态調用業務存儲過程。

服務程序:oracle自動管理的程序,服務程序的數量取決于“程序控制”建立的程序數。服務程序主要工作1、通過“任務讀取”獲得“業務過程”的入參。2、調用“業務過程”生成業務資料。

資料存儲:業務過程處理之後生成的結果。

程序監視:“前台使用者”調用之後任務執行的監控,包括正在執行情況及最終執行結果。

 系統接口設計  

1 程式開發接口設計

此元件向開發人員公布3個系統接口,1個調試接口。

pkg_多線程服務.prc_程序控制

入參:

prm_program   即要調用的業務過程名稱。

prm_parmcount 即對應業務過程的參數個數

pkg_多線程服務.prc_程序停止

直接終止背景正在運作的多線程服務。

pkg_多線程服務.prc_調試使用

prm_parms      即對應業務過程的參數字元串。

因為是動态調用存儲過程,是以sc01中的參數個數必須同業務過程個數嚴格對應,提供此方法主要是讓開發人員調試使用。

任務清單sc01

開發人員要壓入的任務,即業務過程的參數。參數必須以‘|’分隔,并且保證在多線程服務運作的過程中,其他子產品不能對sc01進行dml操作,為實作其他子產品不能操作sc01,在任何dml操作之前必須執行一個語句如下:

selectcount(*)

      into n_exists

      from user_scheduler_jobss

     where s.state = 'running'

and s.job_action = 'pkg_多線程服務.prc_服務程序';

綜上所述執行一個oracle多線程服務,開發人員隻需要做一項工作即壓入正确sc01參數,然後直接調用即可。

2 使用者展示接口設計

前台查詢sc02、sc03視圖

 資料庫結構設計  

1 資料表設計

描述:子產品任務分派表sc01

基于Oracle plsql的多線程程式設計架構 (附存儲過程)

2 視圖設計

描述:運作監視試圖sc02

create or replace view sc02 as

select s.job_creator        現場建立使用者,

      s.job_name            線程名稱,

      s.job_action          過程名稱,

      s.last_start_date           啟動時間,

      s.comments           備注,

      (select count(*)

         from sc01

        where thread_name = lower(s.job_name)

          and status = '0') 未處理數,

          and status = '1') 運作成功數,

          and status = '-1') 運作失敗數

 from user_scheduler_jobs s

 orderby s.job_name;

描述:運作結果監視試圖sc03

create or replace view sc03 as

select s.owner             使用者名,

      s.job_name          線程名稱,

      s.status            線程狀态,

      s.log_date          日志時間,

      s.actual_start_date 線程實際運作時間,

      s.run_duration      線程持續運作時間,

      s.session_id        會話id,

      s.slave_pid         程序id,

      s.additional_info   線程備注資訊,

      (select count(*) from sc01 where thread_name = lower(s.job_name) andstatus = '0') 未處理數,

      (select count(*) from sc01 where thread_name = lower(s.job_name) andstatus = '1') 運作成功數,

      (select count(*) from sc01 where thread_name = lower(s.job_name) andstatus = '-1')運作失敗數

 from user_scheduler_job_run_details s

 order by s.job_name;

3 資料安全性

所需要系統的權限如下:

grant manage scheduler to ahsimis;

grant create any job to ahsimis;

 尚需解決的問題  

如果是rac環境,程式尚不能跨執行個體運作。

原文釋出時間為:2017-01-03

本文來自雲栖社群合作夥伴dbaplus