Tuxedo事務處理
一、什麼是事務
事務(Transaction)是一組邏輯上相關聯的操作,這些操作要麼全都成功執行,要麼全都不執行。事務所含的操作可以分佈在不同的程序甚至不同的機器上。
事務處理必須具備四個基本屬性原子性、一致性、獨立性、耐久性(Atomic、Consistent、 Isolated、Durable也叫ACID屬性):
n 原子性(Atomic)要求一個事務是一個最小的不可分割的單位,以銀行轉帳事務爲例,一個完整的事務處理需要改變轉出和轉入兩個帳戶的資金,只改變一個帳戶是不對的。
n 一致性(Consistent)意味着事務處理正確地轉換了系統狀態。要麼是資金離開一個帳戶進入另一個帳戶,要麼是都保持不變---只有這兩種可能的狀態。如果系統沒有得到轉換後狀態,就回到沒有轉換時的狀態而不會停在中間。
n 獨立性(Isolated)保證任何其他的事務都不能看到一個處在不完整狀態下的事務處理。儘管實際上在錢款被提走而還沒有存入另一個帳號期間有一個遠遠小於一秒的間隔,系統中的其他事務也不會知道的。
n 耐久性(Durable)表示事務處理能在系統失敗時保存完好。一個事務處理應當能夠承受所有的失敗,包括服務器、進程、通信以及媒體失敗等等。
二、事務處理系統的X/Open DTP 模式
由於分佈式事務處理中的操作可能位於許多不同的平臺和數據庫產品 上,爲了協調和控制這些不同的事務操作的行爲,必須有一個事務管理進程,而X/Open標準正是爲此而定義了一個分佈式事務處理(Distributed Transaction Processing, DTP)的模式以及用於事務管理進程和資源管理器交互的XA接口。
X/Open DTP模式的結構圖:
DTP模式有三個模塊:
1) 應用程序(Application Program)通過TX接口向事務管理器定義一個事務邊界,然後向資源管理器提交事務操作;
2) 資源管理器(Resource Manager, RM)是支持XA接口並提供對共享資源訪問接口的管理程序。最常見的RM是數據庫,但象消息隊列或打印機緩衝池等也可以作爲RM,只要它們支持XA接口。
3) 事務管理器(Transaction Manager, TM)爲事務處理編號,監控事務處理全過程並負責事務執行或錯誤恢復。
Tuxedo系統提供了用於創建事務管理器的組件和工具(buildtms)。資源管理器廠商(Oracle, Infomix等)必須提供兼容XA接口的函數庫,這些函數庫用來和Tuxedo的組件及工具一同編譯生成一個Tuxedo的事務管理器。
XA接口及兩步提交協議
DTP模式中事務管理器和資源管理器之間通過XA接口進行通信,XA接口定義了關於如何協調、執行及恢復事務的一個協議規範。兩步提交協議(Two Phase Commit protocol, 2PC)是XA規範的一部分。
在兩步提交協議中的第一步,TM詢問參與一項事務處理的所有RM是否都準備好並能夠執行事務操作。
第二步中,TM檢查RM的應答中是否有不能執行事務操作的應答,若有則通知所有參與事務處理的RM回滾它們所做的事務操作,若沒有則通知RM執行事務操作。
三、Tuxedo服務程序和RM的連接
一個Tuxedo服務程序連接RM是通過調用tpopen()函數實現的,該函數只能在服務程序初始化時(tpsvrinit)調用一次。要關閉和RM的連接,則必須在服務程序終止前調用tpclose()函數。
一 個Tuxedo服務程序中不應該執行CONNECT、COMMIT、ROLLBACK、SAVEPOINT和SET TRANSACTION這些SQL語句,因爲它們會改變事務處理的狀態。同樣,服務程序也不應該執行CREATE、ALTER和RENAME等SQL數據 定義語句,因爲這些語句隱式地執行了COMMIT語句。
四、Tuxedo事務管理器
Tuxedo事務管理器(TMS)必須跟蹤分佈式事務處理的整個流程,記錄足夠的信 息以便在任何時候進行回滾,因此TMS使用事務日誌文件(TLOG)來記錄跟蹤信息,同時爲了區別系統中同時進行的不同事務處理流程,TMS又爲不同的事 務處理分配了一個全局事務編號(GTRIDs)。在事務處理的不同階段,TMS將執行不同的動作如下表:
階段 |
TMS動作 |
應用程序啓動一項事務處理 |
爲事務處理分配一個全局事務編號(GTRIDs) |
啓動事務處理的進程與其它進程通信 |
跟蹤這些參與事務處理的進程 |
事務處理訪問RM |
將相應的GTRIDs傳遞給RM,這樣RM就可以監控哪些數據庫記錄被該事務處理存取 |
應用程序標記一項事務處理將被執行 |
按兩步提交協議執行事務 |
應用程序取消事務處理 |
執行回滾操作 |
有錯誤發生 |
執行回滾操作 |
五、事務處理應用程序開發及管理
開發環境:Linux + Tuxedo + Oracle
1、開發流程圖
2、創建Oracle數據庫及表
先設置Oracle環境變量:
ORACLE_HOME=/home/oracle
ORACLE_SID=linuxdb
PATH=$PATH:$ORACLE_HOME:$ORACLE_HOME/bin:$ORACLE_HOME/dbs
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TUXDIR/lib:/home/oracle/lib
再編寫Sql腳本在數據庫中創建表空間、用戶及數據表:
創建表空間CREATE TABLESPACE
創建用戶CREATE USER
創建表CREATE TABLE
運行Oracle的SQL*PLUS,執行Start命令運行Sql腳本。
3、創建Oracle的TMS
檢查$TUXDIR/udataobj目錄下的RM文件是否有對Oracle8的RM描述
Oracle_XA:xaosw:-L${ORACLE_HOME}/lib -lclntsh
此描述將做爲編譯TMS和服務端程序的編譯選項。
執行Buildtms命令編譯Oracle的TMS服務程序,命令格式如下:
buildtms –o tms_name –r rm_name
-o tms_name: 編譯生成的TMS程序名
-r rm_name: RM描述名
例如:
buildtms –o TMS_ORA –r Oracle_XA
4、客戶端程序
客戶端程序通常作爲一項事務處理的發起者(initiator)調用tpbegin函數,聲明如下:
int tpbegin(unsigned long timeout, long flags)
參數:
unsigned long timeout 事務處理超時時間(秒),若爲0則爲系統最大超時時間
long flags 未定義,應爲0
返回值:
若爲-1則代表出錯,tperrorno爲錯誤代碼。
客戶端程序在調用tpbegin之後可通過tpcall、tpacall、tpconnect等來請求服務端程序,所有被請求的服務將作爲事務處理的參與者被TMS跟蹤記錄,若任何服務請求返回失敗(TPFAIL)則客戶端程序需調用tpabort函數終止當前事務處理,tpabort函數聲明如下:
int tpabort(long flags)
參數:
long flags 未定義,應爲0
返回值:
若爲-1則代表出錯,tperrorno爲錯誤代碼。
若所有請求都成功(TPSUCCESS)則調用tpcommit函數執行事務處理,聲明如下:
int tpcommit(long flags)
參數:
long flags 未定義,應爲0
返回值:
若爲-1則代表出錯,tperrorno爲錯誤代碼。
客戶端程序例子:
/* Begin a Global transaction */
if (tpbegin(30, 0) == -1)
{
printf("ERROR: tpbegin failed (%s)\n", tpstrerror(tperrno));
goto finish;
}
/* send a request to the OPEN_ACCT service and get the reply */
if (tpcall("OPEN_ACCT", (char *)fbfr, 0, (char**)&fbfr, &len, 0) == -1)
{
if (tperrno == TPESVCFAIL &&
fbfr != NULL &&
(server_status=Ffind32(fbfr,STATLIN,0,0)) != 0)
{
/* Server returned failure */
printf("OPEN_ACCT returns failure (%s)\n", server_status);
}
else
{
printf("ERROR: OPEN_ACCT failed (%s)\n", tpstrerror(tperrno));
}
/* Abort the transaction */
tpabort(0);
goto finish;
}
/* Commit the transaction */
if (tpcommit(0) < 0) {
printf("ERROR: tpcommit failed (%s)\n", tpstrerror(tperrno));
goto finish;
}
注意:
1) 只有事務處理的發起者才能調用tpabort或tpcommit函數終止或執行一項事務處理;
2) Tuxedo不支持嵌套事務處理,即發起者在調用tpbegin和tpabort或tpcommit之間不能再調用tpbegin開始一個新的事務處理。
5、服務端程序
服務端程序負責和RM的連接(tpopen,tpclose),同時作爲事務處理的參與者通過Embeded SQL存取Oracle RM中的數據。
服務程序在啓動(tpsvrinit)時調用一次tpopen函數連接到RM,函數聲明如下:
int tpopen(void)
參數:無
返回值:
-1代表出錯
服務程序在退出之前(tpsvrdone)必須調用tpclose函數關閉和RM的連接,函數聲明如下:
int tpclose(void)
參數:無
返回值:
-1代表出錯
Oracle的Embeded SQL語言是Pro*C,具體編程方法可參考《PRO_C程序設計和ORACLE調用》一書。
注意:
1) 在用BuildServer編譯服務端程序時需加上-r rm_name選項指明服務程序所用的RM名稱如-r Oracle_XA
6、配置文件
在Tuxedo應用程序的配置文件中主要修改以下四個部分:
n RESOURCES 設置最大事務處理個數及執行控制標誌
n MACHINES 每臺機器的TLOG配置
n GROUPS 配置RM和TMS的信息
n SERVICES 設置自動事務處理標誌
RESOURCES部分中的參數:
MAXGTT – 限制在一臺機器上某一時刻分配GTRIDs總數,最大值2048,缺省100,可在MACHINES中爲單獨的一臺機器改寫。
CMTRET – 事務執行控制標誌,有兩個值LOGGED和COMPLETE, LOGGED指明tpcommit將在所有事務參與者都準備好執行事務後返回,而COMPLETE指明tpcommit將在所有事務參與者都執行完事務後返回。
MACHINES部分中的參數:
參與事務處理的每臺機器都必須有一個TLOG, TLOG配置參數如下:
TLOGNAME – TLOG名稱
TLOGDEVICE – TLOG文件名(絕對路徑)
TLOGSIZE – TLOG大小,以物理頁爲單位,1 – 2048,缺省爲100(可選)
TLOGOFFSET – TLOG在TLOGDEVICE中偏移量位置(可選)
GROUPS部分中的參數:
TMSNAME – TMS文件名,TMS由buildtms生成, 如TMS_ORA
TMSCOUNT – TMS個數,2 – 10, 缺省爲3
OPENINFO – 連接RM所需要的信息,此信息由RM廠商提供,如Oracle的OPENINFO是"Oracle_XA:Oracle_XA+Acc=P/user1/passwd1+SesTm=0+LogDir=."
CLOSEINFO – 關閉RM所需要的信息(可選)
SERVICES部分中的參數:
AUTOTRAN – 若是Y則service將自動成爲一項事務的發起者,但若在這之前事務已存在則不會開始一項新的事務。缺省值是N
TRANTIME – 爲AUTOTRAN的事務處理設定超時時間
7、TLOG文件
TLOG文件記錄事務處理流程以便在錯誤發生時回滾事務操作,必須爲參與事務處理的每臺機器創建一個TLOG文件。創建TLOG時先進入tmadmin界面,用crdl命令創建設備文件,命令格式爲:
Crdl –b blocks –z config
-b blocks 爲設備文件的大小,以塊(block)爲單位
-z config 爲設備文件名,應和配置文件中TLOGDEVICE相同
然後執行crlog命令創建TLOG, 命令格式爲:
crlog –m machine
-m machine 爲機器名
8、啓動應用程序
用tmboot命令啓動應用程序,但在啓動之前要注意:
對Oracle8.0以上數據 庫,在啓動TMS_ORA之前,先用Oracle的sys用戶(口令:change_on_install)進入Sql*Plus,將對 DBA_PENDING_TRANSACTIONS表的Select權限賦予所有用戶,命令如下:grant select on DBA_PENDING_TRANSACTIONS to public
對Oracle7.0數據庫,在啓動TMS_ORA之前,先用 Oracle的sys用戶(口令:change_on_install)進入Sql*Plus,執行${ORACLE_HOME}/RDBMS /ADMIN/XAVIEW.sql腳本,然後將對v$XAVIEW$視圖的Select權限賦予所有用戶,命令如下:grant select on v$XAVIEW$ to public