亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Java Transaction API概述

系統(tǒng) 2054 0

JTA(Java Transaction API)允許應(yīng)用程序執(zhí)行分布式事務(wù)處理--在兩個或多個網(wǎng)絡(luò)計算機資源上訪問并且更新數(shù)據(jù)。JDBC驅(qū)動程序的JTA支持極大地增強了數(shù)據(jù)訪問能力。

  本文的目的是要提供一個關(guān)于的Java事務(wù)處理API(JTA)的高級的概述,以及與分布式事務(wù)相關(guān)的內(nèi)容。一個事務(wù)處理定義了一個工作邏輯單元,要么徹底成功要么不產(chǎn)生任何結(jié)果。 一個分布式事務(wù)處理只是一個在兩個或更多網(wǎng)絡(luò)資源上訪問和更新數(shù)據(jù)的事務(wù)處理,因此它在那些資源之間必然是等價的。在本文中,我們主要關(guān)心的是如何處理關(guān)系數(shù)據(jù)庫系統(tǒng)。

  我們要討論的分布式事務(wù)處理(DTP)模型中包含的組件是:

    應(yīng)用程序

    應(yīng)用程序服務(wù)器

    事務(wù)管理程序

    資源適配器

    資源管理程序

  在以后的內(nèi)容中,我們將描述這些組件以及它們與JTA和數(shù)據(jù)庫訪問的關(guān)系。

訪問數(shù)據(jù)庫

  最好把分布式事務(wù)處理中包含的組件看作是獨立的過程,而不是考慮它們在一個特定的電腦中的位置。這些組件中的一些可以保存在單機中,或者也可在好幾臺機器之間分布。 下面例子中的圖表可以顯示在一臺特定的電腦上的組件,但是這些操作之間的關(guān)系是必須首要考慮的。

  最簡單的例子:用于本地數(shù)據(jù)庫事務(wù)處理的應(yīng)用程序

  關(guān)系數(shù)據(jù)庫訪問的最簡單的形式僅僅包括應(yīng)用程序、資源管理程序和資源適配器。應(yīng)用程序只不過是發(fā)送請求到數(shù)據(jù)庫并且從數(shù)據(jù)庫中獲取數(shù)據(jù)的最終用戶訪問點

  我們討論的資源管理程序是一個關(guān)系數(shù)據(jù)庫管理系統(tǒng)(RDBMS),比如Oracle或者SQL Server。所有的實際數(shù)據(jù)庫管理都是由這個組件處理的。

  資源適配器是外部空間之間的通信管道組件,或者是請求翻譯器,在本例中,是應(yīng)用程序和資源管理程序。在我們的討論中,這是一個JDBC驅(qū)動程序。

  下面的描述是資源管理程序本地事務(wù)處理的一個描述,也就是說,一個事務(wù)處理被被限制在一個特定的企業(yè)數(shù)據(jù)庫。

  應(yīng)用程序發(fā)送一個用于JDBC驅(qū)動程序數(shù)據(jù)的請求,然后翻譯這個請求并把它通過網(wǎng)絡(luò)發(fā)送到數(shù)據(jù)庫中。 數(shù)據(jù)庫把數(shù)據(jù)發(fā)送回驅(qū)動程序,然后把翻譯的結(jié)果發(fā)送回應(yīng)用程序,如下圖所示:


  這個例子說明了在一個簡化的系統(tǒng)中的基本的信息流;然而,今天的企業(yè)使用的應(yīng)用程序服務(wù)器都添加了其他的組件到這個過程處理中。

應(yīng)用程序服務(wù)器

  應(yīng)用程序服務(wù)器是事務(wù)處理操作的另一個組件。應(yīng)用程序服務(wù)器處理大部分的應(yīng)用程序操作并且獲得最終用戶應(yīng)用程序的一些負(fù)載。基于前面的例子,我們可以看出應(yīng)用程序服務(wù)器在事務(wù)處理上添加了另一個操作層:


  到目前為止,我們的例子說明了單個的本地事務(wù)處理,并且描述了分布式事務(wù)處理模型的五個組件中的四個。第五個組件,事務(wù)管理程序只有當(dāng)事務(wù)將要被分配的時候才會開始被考慮。

分布式事務(wù)處理和事務(wù)管理程序

  像我們前面所提到的,一個分布式事務(wù)處理是一個在兩個或更多網(wǎng)絡(luò)資源上訪問和更新數(shù)據(jù)的事務(wù)處理。

  這些資源可以由好幾個位于一個單獨服務(wù)器上的不同的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)組成,比如說Oracle、SQL Server和Sybase;它們也可以包含存在于若干不同的服務(wù)器上的同一種數(shù)據(jù)庫的若干個實例。在任何情況下,一個分布式事務(wù)處理包括各種的資源管理程序之間的協(xié)同作用。這個協(xié)同作用是事務(wù)管理函數(shù)。

  事務(wù)管理程序負(fù)責(zé)作出要么提交(commit)要么退回(rollback)任何分布式事務(wù)處理的決定。一個提交決定應(yīng)該導(dǎo)致一個成功的事務(wù)處理;而退回操作則是保持?jǐn)?shù)據(jù)庫中的數(shù)據(jù)不變。 JTA指定一個分布式事務(wù)處理中的事務(wù)管理程序和另一個組件之間的標(biāo)準(zhǔn)Java接口:應(yīng)用程序,應(yīng)用程序服務(wù)器和資源管理程序。 這個關(guān)系被顯示在下面的圖表中:



  在事務(wù)管理程序周圍的數(shù)字框框相應(yīng)于JTA的三個接口部分:

  1—UserTransaction—javax.transaction.UserTransaction接口提供能夠編程地控制事務(wù)處理范圍的應(yīng)用程序。 javax.transaction.UserTransaction方法開啟一個全局事務(wù)并且使用調(diào)用線程與事務(wù)處理關(guān)聯(lián)。

  2—Transaction Manager—javax.transaction.TransactionManager接口允許應(yīng)用程序服務(wù)器來控制代表正在管理的應(yīng)用程序的事務(wù)范圍。

  3—XAResource—javax.transaction.xa.XAResource接口是一個基于X/Open CAE Specification的行業(yè)標(biāo)準(zhǔn)XA接口的Java映射。

  注意,一個限制性環(huán)節(jié)是通過JDBC驅(qū)動程序的XAResource接口的支持。JDBC驅(qū)動程序必須支持兩個正常的JDBC交互作用:應(yīng)用程序和/或應(yīng)用程序服務(wù)器,而且以及JTA的XAResource部分。

  編寫應(yīng)用程序水平代碼的開發(fā)者不會關(guān)心分布式事務(wù)處理管理的細(xì)節(jié)。 這是分布式事務(wù)處理基本結(jié)構(gòu)的工作—應(yīng)用程序服務(wù)器、事務(wù)管理程序和JDBC驅(qū)動程序。應(yīng)用程序代碼中唯一的需要注意的就是當(dāng)連接處于一個分布式事務(wù)范圍內(nèi)的時候,不應(yīng)該調(diào)用一個會影響事務(wù)邊界的方法。特別的是,一個應(yīng)用程序不應(yīng)該調(diào)用Connection方法commit、rollback和setAutoCommit(true),因為它們將破壞分布式事務(wù)的基本結(jié)構(gòu)管理。

分布式事務(wù)處理

  事務(wù)管理程序是分布式事務(wù)基本結(jié)構(gòu)的基本組件;然而JDBC驅(qū)動程序和應(yīng)用程序服務(wù)器組件應(yīng)該具備下面的特征:

  驅(qū)動程序應(yīng)該實現(xiàn)JDBC 2.0應(yīng)用程序接口,包括Optional Package接口XADataSource和XAConnection以及JTA接口XAResource。

  應(yīng)用程序服務(wù)器應(yīng)該提供一個DataSource類,用來實現(xiàn)與分布式事務(wù)基本結(jié)的交互以及一個連接池模塊(用于改善性能)。

  分布式事務(wù)處理的第一步就是應(yīng)用程序要發(fā)送一個事務(wù)請求到事務(wù)管理程序。雖然最后的commit/rollback決定把事務(wù)作為一個簡單的邏輯單元來對待,但是仍然可能會包括許多事務(wù)分支。一個事務(wù)分支與一個到包含在分布式事務(wù)中的每個資源管理程序相關(guān)聯(lián)。因此,到三個不同的關(guān)系數(shù)據(jù)庫管理的請求需要三個事務(wù)分支。每個事務(wù)分支必須由本地資源管理程序提交或者返回。事務(wù)管理程序控制事務(wù)的邊界,并且負(fù)責(zé)最后決定應(yīng)該提交或者返回的全部事務(wù)。 這個決定由兩個步驟組成,稱為Two - Phase Commit Protocol。

  在第一步驟中,事務(wù)管理程序輪詢所有包含在分布式事務(wù)中的資源管理程序(關(guān)系數(shù)據(jù)庫管理)來看看哪個可以準(zhǔn)備提交。如果一個資源管理程序不能提交,它將不響應(yīng),并且把事務(wù)的特定部分返回,以便數(shù)據(jù)不被修改。

  在第二步驟中,事務(wù)管理程序判斷否定響應(yīng)的資源管理程序中是否有能夠返回整個事務(wù)的。如果沒有否定響應(yīng)的話,翻譯管理程序提交整個事務(wù)并且返回結(jié)果到應(yīng)用程序中。

  開發(fā)事項管理程序代碼的開發(fā)者必須與所有三個JTA接口有關(guān):UserTransaction、TransactionManager和XAResource,這三個接口都被描述在

  Sun JTA specification中。JDBC驅(qū)動程序開發(fā)者只需要關(guān)心XAResource接口。這個接口是允許一個資源管理程序參與事務(wù)的行業(yè)標(biāo)準(zhǔn)X/Open XA協(xié)議的Java映射。連接XAResource接口的驅(qū)動程序組件負(fù)責(zé)在事務(wù)管理程序和資源管理程序之間擔(dān)任"翻譯"的任務(wù)。下面的章節(jié)提供了XAResource調(diào)用的例子。
JDBC驅(qū)動程序和XAResource

  為了簡化XAResource的說明,這些例子說明了一個應(yīng)用程序在不包含應(yīng)用程序服務(wù)器和事項管理程序的情況下應(yīng)該如何使用JTA。 基本上,這些例子中的應(yīng)用程序也擔(dān)任應(yīng)用程序服務(wù)器和事項管理程序的任務(wù)。大部分的企業(yè)使用事務(wù)管理程序和應(yīng)用程序服務(wù)器,因為它們能夠比一個應(yīng)用程序更能夠高效地管理分布式事務(wù)。 然而遵循這些例子,一個應(yīng)用程序開發(fā)者可以測試在JDBC驅(qū)動程序中的JTA支持的健壯性。而且有一些例子可能不是工作在某個特定的數(shù)據(jù)庫上,這是因為關(guān)聯(lián)在數(shù)據(jù)庫上的一些內(nèi)在的問題。

  在使用JTA之前,你必須首先實現(xiàn)一個Xid類用來標(biāo)識事務(wù)(在普通情況下這將由事務(wù)管理程序來處理)。Xid包含三個元素:formatID、gtrid(全局事務(wù)標(biāo)識符)和bqual(分支修飾詞標(biāo)識符)。

  formatID通常是零,這意味著你將使用OSI CCR(Open Systems Interconnection Commitment, Concurrency和Recovery 標(biāo)準(zhǔn))來命名。如果你要是用另外一種格式,那么formatID應(yīng)該大于零。-1值意味著Xid為無效。

  gtrid和bqual可以包含64個字節(jié)二進制碼來分別標(biāo)識全局事務(wù)和分支事務(wù)。唯一的要求是gtrid和bqual必須是全局唯一的。此外,這可以通過使用指定在OSI CCR中的命名規(guī)則規(guī)范來完成。

  下面的例子說明Xid的實現(xiàn):

import javax.transaction.xa.*;
public class MyXid implements Xid
{
 protected int formatId;
 protected byte gtrid[];
 protected byte bqual[];
 public MyXid()
 {
 }
 public MyXid(int formatId, byte gtrid[], byte bqual[])
 {
  this.formatId = formatId;
  this.gtrid = gtrid;
  this.bqual = bqual;
 }

 public int getFormatId()
 {
  return formatId;
 }

 public byte[] getBranchQualifier()
 {
  return bqual;
 }

 public byte[] getGlobalTransactionId()
 {
  return gtrid;
 }

}


  其次,你需要創(chuàng)建一個你要使用的數(shù)據(jù)庫的數(shù)據(jù)源:

public DataSource getDataSource()
 throws SQLException
 {
  SQLServerDataSource xaDS = new
  com.merant.datadirect.jdbcx.sqlserver.SQLServerDataSource();
  xaDS.setDataSourceName("SQLServer");
  xaDS.setServerName("server");
  xaDS.setPortNumber(1433);
  xaDS.setSelectMethod("cursor");
  return xaDS;
}

  例1—這個例子是用“兩步提交協(xié)議”來提交一個事務(wù)分支:

XADataSource xaDS;
XAConnection xaCon;
XAResource xaRes;
Xid xid;
Connection con;
Statement stmt;
int ret;
xaDS = getDataSource();
xaCon = xaDS.getXAConnection("jdbc_user", "jdbc_password");
xaRes = xaCon.getXAResource();
con = xaCon.getConnection();
stmt = con.createStatement();
xid = new MyXid(100, new byte[]{0x01}, new byte[]{0x02});
try {
  xaRes.start(xid, XAResource.TMNOFLAGS);
  stmt.executeUpdate("insert into test_table values (100)");
  xaRes.end(xid, XAResource.TMSUCCESS);
  ret = xaRes.prepare(xid);
  if (ret == XAResource.XA_OK) {
    xaRes.commit(xid, false);
   }
}
catch (XAException e) {
 e.printStackTrace();
}
finally {
 stmt.close();
 con.close();
 xaCon.close();
}

  因為所有這些例子中的初始化代碼相同或者非常相似,僅僅是一些重要的地方的代碼由不同。

  例2—這個例子,與例1相似,說明了一個返回過程:

xaRes.start(xid, XAResource.TMNOFLAGS);
stmt.executeUpdate("insert into test_table values (100)");
xaRes.end(xid, XAResource.TMSUCCESS);
ret = xaRes.prepare(xid);
if (ret == XAResource.XA_OK) {
 xaRes.rollback(xid);
}

  例3—這個例子說明一個分布式事務(wù)分支如何中止,讓相同的連接做本地事務(wù)處理,以及它們稍后該如何繼續(xù)這個分支。 分布式事務(wù)的兩步提交作用不影響本地事務(wù)。

xid = new MyXid(100, new byte[]{0x01}, new byte[]{0x02});
xaRes.start(xid, XAResource.TMNOFLAGS);
stmt.executeUpdate("insert into test_table values (100)");
xaRes.end(xid, XAResource.TMSUSPEND);
∥這個更新在事務(wù)范圍之外完成,所以它不受XA返回影響。

stmt.executeUpdate("insert into test_table2 values (111)");
xaRes.start(xid, XAResource.TMRESUME);
stmt.executeUpdate("insert into test_table values (200)");
xaRes.end(xid, XAResource.TMSUCCESS);
ret = xaRes.prepare(xid);

if (ret == XAResource.XA_OK) {

xaRes.rollback(xid);

}

  例4—這個例子說明一個XA資源如何分擔(dān)不同的事務(wù)。 創(chuàng)建了兩個事務(wù)分支,但是它們不屬于相同的分布式事務(wù)。 JTA允許XA資源在第一個分支上做一個兩步提交,雖然這個資源仍然與第二個分支相關(guān)聯(lián)。

xid1 = new MyXid(100, new byte[]{0x01}, new byte[]{0x02});
xid2 = new MyXid(100, new byte[]{0x11}, new byte[]{0x22});
xaRes.start(xid1, XAResource.TMNOFLAGS);
stmt.executeUpdate("insert into test_table1 values (100)");
xaRes.end(xid1, XAResource.TMSUCCESS);
xaRes.start(xid2, XAResource.TMNOFLAGS);
ret = xaRes.prepare(xid1);
if (ret == XAResource.XA_OK) {
 xaRes.commit(xid2, false);
}
stmt.executeUpdate("insert into test_table2 values (200)");
xaRes.end(xid2, XAResource.TMSUCCESS);
ret = xaRes.prepare(xid2);
if (ret == XAResource.XA_OK) {
 xaRes.rollback(xid2);
}

  例5—這個例子說明不同的連接上的事務(wù)分支如何連接成為一個單獨的分支,如果它們連接到相同的資源管理程序。這個特點改善了分布式事務(wù)的效率,因為它減少了兩步提交處理的數(shù)目。兩個連接到數(shù)據(jù)庫服務(wù)器上的XA將被創(chuàng)建。每個連接創(chuàng)建它自己的XA資源,正規(guī)的JDBC連接和語句。在第二個XA資源開始一個事務(wù)分支之前,它將察看是否使用和第一個XA資源使用的是同一個資源管理程序。如果這是實例,它將加入在第一個XA連接上創(chuàng)建的第一個分支,而不是創(chuàng)建一個新的分支。 稍后,這個事務(wù)分支使用XA資源來準(zhǔn)備和提交。

xaDS = getDataSource();
xaCon1 = xaDS.getXAConnection("jdbc_user", "jdbc_password");
xaRes1 = xaCon1.getXAResource();
con1 = xaCon1.getConnection();
stmt1 = con1.createStatement();

xid1 = new MyXid(100, new byte[]{0x01}, new byte[]{0x02});
xaRes1.start(xid1, XAResource.TMNOFLAGS);
stmt1.executeUpdate("insert into test_table1 values (100)");
xaRes1.end(xid, XAResource.TMSUCCESS);
xaCon2 = xaDS.getXAConnection("jdbc_user", "jdbc_password");
xaRes2 = xaCon1.getXAResource();
con2 = xaCon1.getConnection();
stmt2 = con1.createStatement();

if (xaRes2.isSameRM(xaRes1)) {
 xaRes2.start(xid1, XAResource.TMJOIN);
 stmt2.executeUpdate("insert into test_table2 values (100)");
 xaRes2.end(xid1, XAResource.TMSUCCESS);
}
else {
 xid2 = new MyXid(100, new byte[]{0x01}, new byte[]{0x03});
 xaRes2.start(xid2, XAResource.TMNOFLAGS);
 stmt2.executeUpdate("insert into test_table2 values (100)");
 xaRes2.end(xid2, XAResource.TMSUCCESS);
 ret = xaRes2.prepare(xid2);
 if (ret == XAResource.XA_OK) {
  xaRes2.commit(xid2, false);
 }
}
ret = xaRes1.prepare(xid1);
if (ret == XAResource.XA_OK) {
 xaRes1.commit(xid1, false);
}

  例6—這個例子說明在錯誤恢復(fù)的階段,如何恢復(fù)準(zhǔn)備好的或者快要完成的事務(wù)分支。 它首先試圖返回每個分支;如果它失敗了,它嘗試著讓資源管理程序丟掉關(guān)于事務(wù)的消息。

MyXid[] xids;
xids = xaRes.recover(XAResource.TMSTARTRSCAN | XAResource.TMENDRSCAN);
for (int i=0; xids!=null && i  try {
  xaRes.rollback(xids[i]);
 }
 catch (XAException ex) {
  try {
   xaRes.forget(xids[i]);
  }
 catch (XAException ex1) {
  System.out.println("rollback/forget failed: " + ex1.errorCode);
 }
}

}

Java Transaction API概述


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 午夜免费福利不卡网址92 | 天天靠天天擦天天摸 | 久久中文字幕免费视频 | 欧美性网 | 国内特级毛片 | 欧美日韩在线成人免费 | 月婷婷色狠狠 | 欧美又黄又嫩大片a级 | 久久久一区二区三区不卡 | 自拍在线视频 | 国产中文字幕免费观看 | 手机在线看片不卡中文字幕 | 亚洲高清在线观看播放 | 国产精品婷婷久久爽一下 | 久久在线精品 | 亚洲国产九九精品一区二区 | 欧美 日韩 国产在线 | 特级a欧美做爰片毛片 | 四虎久久| 国产欧美一区二区另类精品 | 国产96精品 | 欧美大片a一级毛片视频 | 一级黄色录像免费看 | 成人短视频在线 | 欧美另类成人 | 国产一级特黄特色aa毛片 | 中文字幕在线免费播放 | 国产欧美一区二区精品久久久 | 久久精品亚洲精品国产欧美 | 欧美黄色三级视频 | 四虎免费网址 | 精品国产不卡一区二区三区 | 欧美第一页在线观看 | 国产一级毛片一区二区三区 | 久操网址 | 亚洲欧美一区二区三区二厂 | 亚洲另在线日韩综合色 | 九九九热精品 | 中文字幕1区2区 | 一区免费 | 久久精品免费看 |