多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > Java分布式事務原理及應用

Java分布式事務原理及應用

來源:程序員人生   發布時間:2017-03-31 09:39:11 閱讀次數:6204次

學習Java的同學注意了!!! 
學習進程中遇到甚么問題或想獲得學習資源的話,歡迎加入Java學習交換群,群號碼:183993990  我們1起學Java!

引言

  JTA(Java Transaction API)允許利用程序履行散布式事務處理--在兩個或多個網絡計算機資源上訪問并且更新數據。JDBC驅動程序的JTA支持極大地增強了數據訪問能力。

  本文的目的是要提供1個關于的Java事務處理API(JTA)的高級的概述,和與散布式事務相干的內容。1個事務處理定義了1個工作邏輯單元,要末完全成功要末不產生任何結果。 1個散布式事務處理只是1個在兩個或更多網絡資源上訪問和更新數據的事務處理,因此它在那些資源之間必定是等價的。在本文中,我們主要關心的是如何處理關系數據庫系統。

  我們要討論的散布式事務處理(DTP)模型中包括的組件是:

    利用程序

    利用程序服務器

    事務管理程序

    資源適配器

    資源管理程序

  在以后的內容中,我們將描寫這些組件和它們與JTA和數據庫訪問的關系。

  訪問數據庫

  最好把散布式事務處理中包括的組件看做是獨立的進程,而不是斟酌它們在1個特定的電腦中的位置。這些組件中的1些可以保存在單機中,或也可在好幾臺機器之間散布。 下面例子中的圖表可以顯示在1臺特定的電腦上的組件,但是這些操作之間的關系是必須重要斟酌的。

  最簡單的例子:用于本地數據庫事務處理的利用程序

  關系數據庫訪問的最簡單的情勢僅僅包括利用程序、資源管理程序和資源適配器。利用程序只不過是發送要求到數據庫并且從數據庫中獲得數據的終究用戶訪問點

  我們討論的資源管理程序是1個關系數據庫管理系統(RDBMS),比如Oracle或SQL Server。所有的實際數據庫管理都是由這個組件處理的。

  資源適配器是外部空間之間的通訊管道組件,或是要求翻譯器,在本例中,是利用程序和資源管理程序。在我們的討論中,這是1個JDBC驅動程序。

  下面的描寫是資源管理程序本地事務處理的1個描寫,也就是說,1個事務處理被被限制在1個特定的企業數據庫

  利用程序發送1個用于JDBC驅動程序數據的要求,然后翻譯這個要求并把它通過網絡發送到數據庫中。 數據庫把數據發送回驅動程序,然后把翻譯的結果發送回利用程序,以下圖所示:

 

 

 


 

這個例子說明了在1個簡化的系統中的基本的信息流;但是,今天的企業使用的利用程序服務器都添加了其他的組件到這個進程處理中。

 

  利用程序服務器

  利用程序服務器是事務處理操作的另外一個組件。利用程序服務器處理大部份的利用程序操作并且取得終究用戶利用程序的1些負載。基于前面的例子,我們可以看出利用程序服務器在事務處理上添加了另外一個操作層:


 


  

到目前為止,我們的例子說明了單個的本地事務處理,并且描寫了散布式事務處理模型的5個組件中的4個。第5個組件,事務管理程序只有當事務將要被分配的時候才會開始被斟酌。

  散布式事務處理和事務管理程序

  像我們前面所提到的,1個散布式事務處理是1個在兩個或更多網絡資源上訪問和更新數據的事務處理。

  這些資源可以由好幾個位于1個單獨服務器上的不同的關系型數據庫管理系統組成,比如說Oracle、SQL Server和Sybase;它們也能夠包括存在于若干不同的服務器上的同1種數據庫的若干個實例。在任何情況下,1個散布式事務處理包括各種的資源管理程序之間的協同作用。這個協同作用是事務管理函數。

  事務管理程序負責作出要末提交(commit)要末退回(rollback)任何散布式事務處理的決定。1個提交決定應當致使1個成功的事務處理;而退回操作則是保持數據庫中的數據不變。 JTA指定1個散布式事務處理中的事務管理程序和另外一個組件之間的標準Java接口:利用程序,利用程序服務器和資源管理程序。 這個關系被顯示在下面的圖表中:


 



  在事務管理程序周圍的數字框框相應于JTA的3個接口部份:

  1—UserTransaction—javax.transaction.UserTransaction接口提供能夠編程地控制事務處理范圍的利用程序。 javax.transaction.UserTransaction方法開啟1個全局事務并且使用調用線程與事務處理關聯。

  2—Transaction Manager—javax.transaction.TransactionManager接口允許利用程序服務器來控制代表正在管理的利用程序的事務范圍。

  3—XAResource—javax.transaction.xa.XAResource接口是1個基于X/Open CAE Specification的行業標準XA接口的Java映照。

  注意,1個限制性環節是通過JDBC驅動程序的XAResource接口的支持。JDBC驅動程序必須支持兩個正常的JDBC交互作用:利用程序和/或利用程序服務器,而且和JTA的XAResource部份。

  編寫利用程序水平代碼的開發者不會關心散布式事務處理管理的細節。 這是散布式事務處理基本結構的工作—利用程序服務器、事務管理程序和JDBC驅動程序。利用程序代碼中唯1的需要注意的就是當連接處于1個散布式事務范圍內的時候,不應當調用1個會影響事務邊界的方法。特別的是,1個利用程序不應當調用Connection方法commit、rollback和setAutoCommit(true),由于它們將破壞散布式事務的基本結構管理。

  散布式事務處理

  事務管理程序是散布式事務基本結構的基本組件;但是JDBC驅動程序和利用程序服務器組件應當具有下面的特點:

  驅動程序應當實現JDBC 2.0利用程序接口,包括Optional Package接口XADataSource和XAConnection和JTA接口XAResource。

  利用程序服務器應當提供1個DataSource類,用來實現與散布式事務基本結的交互和1個連接池模塊(用于改良性能)。

  散布式事務處理的第1步就是利用程序要發送1個事務要求到事務管理程序。雖然最后的commit/rollback決定把事務作為1個簡單的邏輯單元來對待,但是依然可能會包括許多事務分支。1個事務分支與1個到包括在散布式事務中的每一個資源管理程序相干聯。因此,到3個不同的關系數據庫管理的要求需要3個事務分支。每一個事務分支必須由本地資源管理程序提交或返回。事務管理程序控制事務的邊界,并且負責最后決定應當提交或返回的全部事務。 這個決定由兩個步驟組成,稱為Two - Phase Commit Protocol。

  在第1步驟中,事務管理程序輪詢所有包括在散布式事務中的資源管理程序(關系數據庫管理)來看看哪一個可以準備提交。如果1個資源管理程序不能提交,它將不響應,并且把事務的特定部份返回,以便數據不被修改。

  在第2步驟中,事務管理程序判斷否定響應的資源管理程序中是不是有能夠返回全部事務的。如果沒有否定響應的話,翻譯管理程序提交全部事務并且返回結果到利用程序中。

  開發事項管理程序代碼的開發者必須與所有3個JTA接口有關:UserTransaction、TransactionManager和XAResource,這3個接口都被描寫在

  Sun JTA specification中。JDBC驅動程序開發者只需要關心XAResource接口。這個接口是允許1個資源管理程序參與事務的行業標準X/Open XA協議的Java映照。連接XAResource接口的驅動程序組件負責在事務管理程序和資源管理程序之間擔負"翻譯"的任務。下面的章節提供了XAResource調用的例子。

 

  JDBC驅動程序和XAResource

  為了簡化XAResource的說明,這些例子說明了1個利用程序在不包括利用程序服務器和事項管理程序的情況下應當如何使用JTA。 基本上,這些例子中的利用程序也擔負利用程序服務器和事項管理程序的任務。大部份的企業使用事務管理程序和利用程序服務器,由于它們能夠比1個利用程序更能夠高效地管理散布式事務。 但是遵守這些例子,1個利用程序開發者可以測試在JDBC驅動程序中的JTA支持的硬朗性。而且有1些例子可能不是工作在某個特定的數據庫上,這是由于關聯在數據庫上的1些內在的問題。

  在使用JTA之前,你必須首先實現1個Xid類用來標識事務(在普通情況下這將由事務管理程序來處理)。Xid包括3個元素:formatID、gtrid(全局事務標識符)和bqual(分支修飾詞標識符)。

  formatID通常是零,這意味著你將使用OSI CCR(Open Systems Interconnection Commitment, Concurrency和Recovery 標準)來命名。如果你要是用另外1種格式,那末formatID應當大于零。⑴值意味著Xid為無效。

  gtrid和bqual可以包括64個字節2進制碼來分別標識全局事務和分支事務。唯1的要求是gtrid和bqual必須是全局唯1的。另外,這可以通過使用指定在OSI CCR中的命名規則規范來完成。

  下面的例子說明Xid的實現:

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;
 }

}



  其次,你需要創建1個你要使用的數據庫的數據源:

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—這個例子是用“兩步提交協議”來提交1個事務分支:

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();
}


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

  例2—這個例子,與例1相似,說明了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—這個例子說明1個散布式事務分支如何中斷,讓相同的連接做本地事務處理,和它們稍后該如何繼續這個分支。 散布式事務的兩步提交作用不影響本地事務。

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);
這個更新在事務范圍以外完成,所以它不受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—這個例子說明1個XA資源如何分擔不同的事務。 創建了兩個事務分支,但是它們不屬于相同的散布式事務。 JTA允許XA資源在第1個分支上做1個兩步提交,雖然這個資源依然與第2個分支相干聯。

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—這個例子說明不同的連接上的事務分支如何連接成為1個單獨的分支,如果它們連接到相同的資源管理程序。這個特點改良了散布式事務的效力,由于它減少了兩步提交處理的數目。兩個連接到數據庫服務器上的XA將被創建。每一個連接創建它自己的XA資源,正規的JDBC連接和語句。在第2個XA資源開始1個事務分支之前,它將觀察是不是使用和第1個XA資源使用的是同1個資源管理程序。如果這是實例,它將加入在第1個XA連接上創建的第1個分支,而不是創建1個新的分支。 稍后,這個事務分支使用XA資源來準備和提交。

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—這個例子說明在毛病恢復的階段,如何恢復準備好的或快要完成的事務分支。 它首先試圖返回每一個分支;如果它失敗了,它嘗試著讓資源管理程序丟掉關于事務的消息。

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的同學注意了!!! 
學習進程中遇到甚么問題或想獲得學習資源的話,歡迎加入Java學習交換群,群號碼:183993990  我們1起學Java!

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产精品揄拍100视频最近 | 影视先锋av资源噜噜 | 国产精品国产三级国产专区5o | 中文字幕一区视频 | 亚洲日本中文 | 欧美激情区 | 日本xxxx护士hd| 欧美精品一区二区三区四区 | 欧美黑人巨大xxxxx | 麻豆精品国产自产在线 | 成人在线小视频 | 国产91一区二区在线播放不卡 | 亚洲视频在线免费观看 | 欧美日韩国 | 久久精品亚洲99一区二区 | 精品国产免费一区二区三区五区 | 亚洲伊人久久大香线蕉综合图片 | 乡下女色又黄一级毛片 | 日本系列第_1_页_俺去了 | 亚洲黄色在线视频 | 中文字幕播放 | 欧美丝袜高跟鞋一区二区 | 色吊丝在线观看国产 | 国产福利在线 | 日本免费在线一区 | 美国一级免费毛片 | 亚洲国产成人精品一区二区三区 | 日本一道本中文字幕 | 亚洲一区二区三区精品影院 | 91成年影院 | 国产精品免费_区二区三区观看 | 亚洲图片校园春色 | 国美女福利视频午夜精品 | 国产v精品成人免费视频71sao | 午夜免费福利在线 | 国产欧美日韩在线一区二区不卡 | 欧美日韩v| 国产一区二区三区在线免费观看 | 色综合美国色农夫网 | 国产免费亚洲 | 国产亚洲一区在线 |