1. 程式人生 > >[java][db]JAVA分散式事務原理及應用

[java][db]JAVA分散式事務原理及應用

JTA(Java Transaction API)允許應用程式執行分散式事務處理--在兩個或多個網路計算機資源上訪問並且更新資料。JDBC驅動程式的JTA支援極大地增強了資料訪問能力。 

  本文的目的是要提供一個關於的Java事務處理API(JTA)的高階的概述,以及與分散式事務相關的內容。一個事務處理定義了一個工作邏輯單元,要麼徹底成功要麼不產生任何結果。 一個分散式事務處理只是一個在兩個或更多網路資源上訪問和更新資料的事務處理,因此它在那些資源之間必然是等價的。在本文中,我們主要關心的是如何處理關係資料庫系統。 

  我們要討論的分散式事務處理(DTP)模型中包含的元件是: 

    應用程式 


    應用程式伺服器 

    事務管理程式 

    資源介面卡 

    資源管理程式 

  在以後的內容中,我們將描述這些元件以及它們與JTA和資料庫訪問的關係。 

  訪問資料庫 

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

  最簡單的例子:用於本地資料庫事務處理的應用程式 

  關係資料庫訪問的最簡單的形式僅僅包括應用程式、資源管理程式和資源介面卡。應用程式只不過是傳送請求到資料庫並且從資料庫中獲取資料的終端使用者訪問點 


  我們討論的資源管理程式是一個關係資料庫管理系統(RDBMS),比如Oracle或者SQL Server。所有的實際資料庫管理都是由這個元件處理的。 

  資源介面卡是外部空間之間的通訊管道元件,或者是請求翻譯器,在本例中,是應用程式和資源管理程式。在我們的討論中,這是一個JDBC驅動程式。 

  下面的描述是資源管理程式本地事務處理的一個描述,也就是說,一個事務處理被被限制在一個特定的企業資料庫。 

  應用程式傳送一個用於JDBC驅動程式資料的請求,然後翻譯這個請求並把它通過網路傳送到資料庫中。 資料庫把資料傳送回驅動程式,然後把翻譯的結果傳送迴應用程式,如下圖所示:

 


這個例子說明了在一個簡化的系統中的基本的資訊流;然而,今天的企業使用的應用程式伺服器都添加了其他的元件到這個過程處理中。 




  應用程式伺服器 

  應用程式伺服器是事務處理操作的另一個元件。應用程式伺服器處理大部分的應用程式操作並且獲得終端使用者應用程式的一些負載。基於前面的例子,我們可以看出應用程式伺服器在事務處理上添加了另一個操作層: 




到目前為止,我們的例子說明了單個的本地事務處理,並且描述了分散式事務處理模型的五個元件中的四個。第五個元件,事務管理程式只有當事務將要被分配的時候才會開始被考慮。 

  分散式事務處理和事務管理程式 

  像我們前面所提到的,一個分散式事務處理是一個在兩個或更多網路資源上訪問和更新資料的事務處理。 

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

  事務管理程式負責作出要麼提交(commit)要麼退回(rollback)任何分散式事務處理的決定。一個提交決定應該導致一個成功的事務處理;而退回操作則是保持資料庫中的資料不變。 JTA指定一個分散式事務處理中的事務管理程式和另一個元件之間的標準Java介面:應用程式,應用程式伺服器和資源管理程式。 這個關係被顯示在下面的圖表中: 

  在事務管理程式周圍的數字框框相應於JTA的三個介面部分: 

  1—UserTransaction—javax.transaction.UserTransaction介面提供能夠程式設計地控制事務處理範圍的應用程式。 javax.transaction.UserTransaction方法開啟一個全域性事務並且使用呼叫執行緒與事務處理關聯。 

  2—Transaction Manager—javax.transaction.TransactionManager介面允許應用程式伺服器來控制代表正在管理的應用程式的事務範圍。 

  3—XAResource—javax.transaction.xa.XAResource介面是一個基於X/Open CAE Specification的行業標準XA介面的Java對映。 

  注意,一個限制性環節是通過JDBC驅動程式的XAResource介面的支援。JDBC驅動程式必須支援兩個正常的JDBC互動作用:應用程式和/或應用程式伺服器,而且以及JTA的XAResource部分。 

  編寫應用程式水平程式碼的開發者不會關心分散式事務處理管理的細節。 這是分散式事務處理基本結構的工作—應用程式伺服器、事務管理程式和JDBC驅動程式。應用程式程式碼中唯一的需要注意的就是當連線處於一個分散式事務範圍內的時候,不應該呼叫一個會影響事務邊界的方法。特別的是,一個應用程式不應該呼叫Connection方法commit、rollback和setAutoCommit(true),因為它們將破壞分散式事務的基本結構管理。 

  分散式事務處理 

  事務管理程式是分散式事務基本結構的基本元件;然而JDBC驅動程式和應用程式伺服器元件應該具備下面的特徵: 

  驅動程式應該實現JDBC 2.0應用程式介面,包括Optional Package介面XADataSource和XAConnection以及JTA介面XAResource。 

  應用程式伺服器應該提供一個DataSource類,用來實現與分散式事務基本結的互動以及一個連線池模組(用於改善效能)。 

  分散式事務處理的第一步就是應用程式要傳送一個事務請求到事務管理程式。雖然最後的commit/rollback決定把事務作為一個簡單的邏輯單元來對待,但是仍然可能會包括許多事務分支。一個事務分支與一個到包含在分散式事務中的每個資源管理程式相關聯。因此,到三個不同的關係資料庫管理的請求需要三個事務分支。每個事務分支必須由本地資源管理程式提交或者返回。事務管理程式控制事務的邊界,並且負責最後決定應該提交或者返回的全部事務。 這個決定由兩個步驟組成,稱為Two - Phase Commit Protocol。 

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

  在第二步驟中,事務管理程式判斷否定響應的資源管理程式中是否有能夠返回整個事務的。如果沒有否定響應的話,翻譯管理程式提交整個事務並且返回結果到應用程式中。 

  開發事項管理程式程式碼的開發者必須與所有三個JTA介面有關:UserTransaction、TransactionManager和XAResource,這三個介面都被描述在 

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

  JDBC驅動程式和XAResource 

  為了簡化XAResource的說明,這些例子說明了一個應用程式在不包含應用程式伺服器和事項管理程式的情況下應該如何使用JTA。 基本上,這些例子中的應用程式也擔任應用程式伺服器和事項管理程式的任務。大部分的企業使用事務管理程式和應用程式伺服器,因為它們能夠比一個應用程式更能夠高效地管理分散式事務。 然而遵循這些例子,一個應用程式開發者可以測試在JDBC驅動程式中的JTA支援的健壯性。而且有一些例子可能不是工作在某個特定的資料庫上,這是因為關聯在資料庫上的一些內在的問題。 

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

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

  gtrid和bqual可以包含64個位元組二進位制碼來分別標識全域性事務和分支事務。唯一的要求是gtrid和bqual必須是全域性唯一的。此外,這可以通過使用指定在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; 
 } 






  其次,你需要建立一個你要使用的資料庫的資料來源: 


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


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—這個例子說明一個分散式事務分支如何中止,讓相同的連線做本地事務處理,以及它們稍後該如何繼續這個分支。 分散式事務的兩步提交作用不影響本地事務。 


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—這個例子說明一個XA資源如何分擔不同的事務。 建立了兩個事務分支,但是它們不屬於相同的分散式事務。 JTA允許XA資源在第一個分支上做一個兩步提交,雖然這個資源仍然與第二個分支相關聯。 


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—這個例子說明不同的連線上的事務分支如何連線成為一個單獨的分支,如果它們連線到相同的資源管理程式。這個特點改善了分散式事務的效率,因為它減少了兩步提交處理的數目。兩個連線到資料庫伺服器上的XA將被建立。每個連線建立它自己的XA資源,正規的JDBC連線和語句。在第二個XA資源開始一個事務分支之前,它將察看是否使用和第一個XA資源使用的是同一個資源管理程式。如果這是例項,它將加入在第一個XA連線上建立的第一個分支,而不是建立一個新的分支。 稍後,這個事務分支使用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)"); 

相關推薦

[java][db]JAVA分散式事務原理應用

JTA(Java Transaction API)允許應用程式執行分散式事務處理--在兩個或多個網路計算機資源上訪問並且更新資料。JDBC驅動程式的JTA支援極大地增強了資料訪問能力。   本文的目的是要提供一個關於的Java事務處理API(JTA)的高階的概述,以及與分散

分散式事務原理解決方案

1 引言 分散式事務是企業整合中的一個技術難點,也是每一個分散式系統架構中都會涉及到的一個東西,特別是在這幾年越來越火的微服務架構中,幾乎可以說是無法避免,本文就圍繞單機事務,分散式事務以及分散式事務的處理方式來展開。 2 事務 事務提供一種“要麼什麼都不做,要麼做全套(All or Nothing)”

Java核心機制:反射機制的原理應用方法

一、java的核心機制 java有兩種核心機制:java虛擬機器(JavaVirtual Machine)與垃圾收集機制(Garbage collection): 1、Java虛擬機器:是執行所有Java程式的抽象計算機,是Java語言的執行環境,在其上面執行Java程式碼編譯後的位元組碼程式,

java中的subString具體解釋應用

clas ava 取字符 pos 指定 rac gin pop java substring(參數)是java中截取字符串的一個方法 有兩種傳參方式 一種是public String substring(int beginIndex) 返回一個新的字符串,它是此字符

Java中IO流的分類應用

serializa 對象序列化 col io流 pip ava 應用 指定 pipe =======I/O========================================================================== File:代表了磁

java分布式事務解決方案

ted 即使 線下 提升 nts 20px lan term 不能 1、什麽是分布式事務 分布式事務就是指事務的參與者、支持事務的服務器、資源服務器以及事務管理器分別位於不同的分布式系統的不同節點之上。以上是百度百科的解釋,簡單的說,就是一次大的操作由不同的小操作組成,這些

【轉】Java學習---快速掌握RPC原理實現

消費者 阿裏 局限 kryo nes 很多 cal 網絡 href 【原文】https://www.toutiao.com/i6592365493435236872/ ?RPC概述 RPC(Remote Procedure Call)即遠程過程調用,也就是說兩臺服務器A,

深入理解Java中的底層阻塞原理實現

更多 安全 posix pla static events time() 方便 原理 談到阻塞,相信大家都不會陌生了。阻塞的應用場景真的多得不要不要的,比如 生產-消費模式,限流統計等等。什麽 ArrayBlockingQueue、 LinkedBlockingQueue、

JAVA RMI分布式原理應用

讀取 create host 實現邏輯 傳遞 not 綁定 per args RMI(Remote Method Invocation)是JAVA早期版本(JDK 1.1)提供的分布式應用解決方案,它作為重要的API被廣泛的應用在EJB中。隨著互聯網應用的發展,分布式

java垃圾回收機制的原理優缺點

  優點:a.不需要考慮記憶體管理, b.可以有效的防止記憶體洩漏,有效的利用可使用的記憶體, c.由於有垃圾回收機制,Java中的物件不再有"作用域"的概念,只有物件的引用才有"作用域" 原

java基礎】ConcurrentHashMap實現原理原始碼分析

  ConcurrentHashMap是Java併發包中提供的一個執行緒安全且高效的HashMap實現(若對HashMap的實現原理還不甚瞭解,可參考我的另一篇文章),ConcurrentHashMap在併發程式設計的場景中使用頻率非常之高,本文就來分析下Concurre

分散式服務框架Zookeeper介紹、原理應用

轉載:https://www.jianshu.com/p/bf32e44d3113 分散式服務框架Zookeeper介紹、原理及應用 Zookeeper簡介 Zookeeper 分散式服務框架是 Apache Hadoop 的一個子專案,它主要是用來解決分散式應用中經常遇到的一些資料管理

Java】Java8 HashMap工作原理實現

1 、概述 從本文你可以學到 什麼時候會使用HashMap?他有什麼特點? 你知道HashMap的工作原理嗎? 你知道get和put的原理嗎?equals()和hashCode()的都有什麼作用? 你知道hash的實現嗎?

Java中synchronized的實現原理應用

Java中的每一個物件都可以作為鎖,而在Synchronized實現同步的幾種方式中分別為: 普通同步方法:鎖是當前例項物件 靜態同步方法:鎖是當前類的Class物件 同步方法塊:鎖是Synchronized括號裡配置的物件 任何一個物件都一個Monit

java中的遞迴思想應用

遞迴就是自己調自己,最需要注意的就是結束條件,否則可能就是死迴圈,導致記憶體溢位 public T a(Object x,Object y) {   if(條件true) {   a(x1,y1); } else {   return f(x,y);

java執行緒池ThreadPoolExecutor原理使用

其構造方法為public class ThreadPoolExecutor extends AbstractExecutorService{<span style="white-space:pre"> </span><div class="li

Java 中 synchronized 的實現原理偏向鎖、輕量級鎖、自旋鎖、公平鎖簡介

    在多執行緒程式設計中,synchronized 一直都是元老級別的存在,很多人都稱之為重量級鎖。本文來簡單介紹synchronized的實現原理,以及為減少獲得鎖和釋放鎖所帶來的效能損耗而引進的偏向鎖與輕量級鎖。     Java中使用synchronized來實現

Java 集合:TreeMap工作原理實現

前言 本文轉載自:點這裡,該部落格非常不錯,建議前去看看。 正文 1. 概述 A Red-Black tree based NavigableMap implementation. The map is sorted according to the natura

java 中泛型的原理以及應用場景

Java從1.5之後支援泛型,泛型的本質是引數化型別,也就是說所操作的資料型別被指定為一個引數。這種引數型別可以用在類、介面和方法的建立中,分別稱為泛型類、泛型介面、泛型方法。 入不支援泛型,則表現為支援Object,不是特定的泛型。 泛型是對 Java 語言的型別系統的一

Java實現SSH模式加密原理程式碼

一、SSH加密原理 SSH是先通過非對稱加密告訴服務端一個對稱加密口令,然後進行驗證使用者名稱和密碼的時候,使用雙方已經知道的加密口令進行加密和解密,見下圖: 解釋:SSH中為什麼要使用非對稱加密,又使用對稱加密,到底有什麼用處?到底安全不安全?既然後來又使用了對稱加密,開始的時候為什麼還要用非對稱加密?