最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中JDBC事務(wù)與JTA分布式事務(wù)總結(jié)與區(qū)別

 更新時(shí)間:2016年11月01日 15:25:51   作者:boonya  
Java事務(wù)的類型有三種:JDBC事務(wù)、JTA(Java Transaction API)事務(wù)、容器事務(wù),本文詳細(xì)介紹了JDBC事務(wù)與JTA分布式事務(wù),有需要的可以了解一下。

Java事務(wù)的類型有三種:JDBC事務(wù)、JTA(Java Transaction API)事務(wù)、容器事務(wù)。常見(jiàn)的容器事務(wù)如Spring事務(wù),容器事務(wù)主要是J2EE應(yīng)用服務(wù)器提供的,容器事務(wù)大多是基于JTA完成,這是一個(gè)基于JNDI的,相當(dāng)復(fù)雜的API實(shí)現(xiàn)。所以本文暫不討論容器事務(wù)。本文主要介紹J2EE開(kāi)發(fā)中兩個(gè)比較基本的事務(wù):JDBC事務(wù)和JTA事務(wù)。

JDBC事務(wù)

JDBC的一切行為包括事務(wù)是基于一個(gè)Connection的,在JDBC中是通過(guò)Connection對(duì)象進(jìn)行事務(wù)管理。在JDBC中,常用的和事務(wù)相關(guān)的方法是: setAutoCommit、commit、rollback等。

下面看一個(gè)簡(jiǎn)單的JDBC事務(wù)代碼:

public void JdbcTransfer() {  
  java.sql.Connection conn = null; 
   try{  
    conn = conn =DriverManager.getConnection("jdbc:oracle:thin:@host:1521:SID","username","userpwd"); 
     // 將自動(dòng)提交設(shè)置為 false, 
     //若設(shè)置為 true 則數(shù)據(jù)庫(kù)將會(huì)把每一次數(shù)據(jù)更新認(rèn)定為一個(gè)事務(wù)并自動(dòng)提交 
     conn.setAutoCommit(false); 
 
     stmt = conn.createStatement();  
     // 將 A 賬戶中的金額減少 500  
     stmt.execute("\ 
     update t_account set amount = amount - 500 where account_id = 'A'"); 
     // 將 B 賬戶中的金額增加 500  
     stmt.execute("\ 
     update t_account set amount = amount + 500 where account_id = 'B'"); 
 
     // 提交事務(wù) 
     conn.commit(); 
     // 事務(wù)提交:轉(zhuǎn)賬的兩步操作同時(shí)成功 
   } catch(SQLException sqle){       
     try{  
       // 發(fā)生異常,回滾在本事務(wù)中的操做 
      conn.rollback(); 
       // 事務(wù)回滾:轉(zhuǎn)賬的兩步操作完全撤銷 
       stmt.close();  
       conn.close();  
     }catch(Exception ignore){  
 
     }  
     sqle.printStackTrace();  
   }  
} 

上面的代碼實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的轉(zhuǎn)賬功能,通過(guò)事務(wù)來(lái)控制轉(zhuǎn)賬操作,要么都提交,要么都回滾。

JDBC事務(wù)的優(yōu)缺點(diǎn)

JDBC為使用Java進(jìn)行數(shù)據(jù)庫(kù)的事務(wù)操作提供了最基本的支持。通過(guò)JDBC事務(wù),我們可以將多個(gè)SQL語(yǔ)句放到同一個(gè)事務(wù)中,保證其ACID特性。JDBC事務(wù)的主要優(yōu)點(diǎn)就是API比較簡(jiǎn)單,可以實(shí)現(xiàn)最基本的事務(wù)操作,性能也相對(duì)較好。

但是,JDBC事務(wù)有一個(gè)局限:一個(gè) JDBC 事務(wù)不能跨越多個(gè)數(shù)據(jù)庫(kù)?。。∷?,如果涉及到多數(shù)據(jù)庫(kù)的操作或者分布式場(chǎng)景,JDBC事務(wù)就無(wú)能為力了。

JTA事務(wù)

為什么需要JTA

通常,JDBC事務(wù)就可以解決數(shù)據(jù)的一致性等問(wèn)題,鑒于他用法相對(duì)簡(jiǎn)單,所以很多人關(guān)于Java中的事務(wù)只知道有JDBC事務(wù),或者有人知道框架中的事務(wù)(比如Hibernate、Spring)等。但是,由于JDBC無(wú)法實(shí)現(xiàn)分布式事務(wù),而如今的分布式場(chǎng)景越來(lái)越多,所以,JTA事務(wù)就應(yīng)運(yùn)而生。

如果,你在工作中沒(méi)有遇到JDBC事務(wù)無(wú)法解決的場(chǎng)景,那么只能說(shuō)你做的項(xiàng)目還都太小。拿電商網(wǎng)站來(lái)說(shuō),我們一般把一個(gè)電商網(wǎng)站橫向拆分成商品模塊、訂單模塊、購(gòu)物車模塊、消息模塊、支付模塊等。然后我們把不同的模塊部署到不同的機(jī)器上,各個(gè)模塊之間通過(guò)遠(yuǎn)程服務(wù)調(diào)用(RPC)等方式進(jìn)行通信。以一個(gè)分布式的系統(tǒng)對(duì)外提供服務(wù)。

一個(gè)支付流程就要和多個(gè)模塊進(jìn)行交互,每個(gè)模塊都部署在不同的機(jī)器中,并且每個(gè)模塊操作的數(shù)據(jù)庫(kù)都不一致,這時(shí)候就無(wú)法使用JDBC來(lái)管理事務(wù)。我們看一段代碼:

/** 支付訂單處理 **/ 
@Transactional(rollbackFor = Exception.class) 
public void completeOrder() { 
  orderDao.update(); // 訂單服務(wù)本地更新訂單狀態(tài) 
  accountService.update(); // 調(diào)用資金賬戶服務(wù)給資金帳戶加款 
  pointService.update(); // 調(diào)用積分服務(wù)給積分帳戶增加積分 
  accountingService.insert(); // 調(diào)用會(huì)計(jì)服務(wù)向會(huì)計(jì)系統(tǒng)寫入會(huì)計(jì)原始憑證 
  merchantNotifyService.notify(); // 調(diào)用商戶通知服務(wù)向商戶發(fā)送支付結(jié)果通知 
} 

上面的代碼是一個(gè)簡(jiǎn)單的支付流程的操作,其中調(diào)用了五個(gè)服務(wù),這五個(gè)服務(wù)都通過(guò)RPC的方式調(diào)用,請(qǐng)問(wèn)使用JDBC如何保證事務(wù)一致性?我在方法中增加了@Transactional注解,但是由于采用調(diào)用了分布式服務(wù),該事務(wù)并不能達(dá)到ACID的效果。

JTA事務(wù)比JDBC事務(wù)更強(qiáng)大。一個(gè)JTA事務(wù)可以有多個(gè)參與者,而一個(gè)JDBC事務(wù)則被限定在一個(gè)單一的數(shù)據(jù)庫(kù)連接。下列任一個(gè)Java平臺(tái)的組件都可以參與到一個(gè)JTA事務(wù)中:JDBC連接、JDO PersistenceManager 對(duì)象、JMS 隊(duì)列、JMS 主題、企業(yè)JavaBeans(EJB)、一個(gè)用J2EE Connector Architecture 規(guī)范編譯的資源分配器。

JTA的定義

Java事務(wù)API(Java Transaction API,簡(jiǎn)稱JTA ) 是一個(gè)Java企業(yè)版 的應(yīng)用程序接口,在Java環(huán)境中,允許完成跨越多個(gè)XA資源的分布式事務(wù)。

JTA和它的同胞Java事務(wù)服務(wù)(JTS;Java TransactionService),為J2EE平臺(tái)提供了分布式事務(wù)服務(wù)。不過(guò)JTA只是提供了一個(gè)接口,并沒(méi)有提供具體的實(shí)現(xiàn),而是由j2ee服務(wù)器提供商 根據(jù)JTS規(guī)范提供的,常見(jiàn)的JTA實(shí)現(xiàn)有以下幾種:

1.J2EE容器所提供的JTA實(shí)現(xiàn)(JBoss)

2.獨(dú)立的JTA實(shí)現(xiàn):如JOTM,Atomikos.這些實(shí)現(xiàn)可以應(yīng)用在那些不使用J2EE應(yīng)用服務(wù)器的環(huán)境里用以提供分布事事務(wù)保證。如Tomcat,Jetty以及普通的java應(yīng)用。

JTA里面提供了 java.transaction.UserTransaction ,里面定義了下面幾個(gè)方法

  •  begin:開(kāi)啟一個(gè)事務(wù)
  • commit:提交當(dāng)前事務(wù)
  • rollback:回滾當(dāng)前事務(wù)
  • setRollbackOnly:把當(dāng)前事務(wù)標(biāo)記為回滾
  • setTransactionTimeout:設(shè)置事務(wù)的事件,超過(guò)這個(gè)事件,就拋出異常,回滾事務(wù)

這里,值得注意的是,不是使用了UserTransaction就能把普通的JDBC操作直接轉(zhuǎn)成JTA操作,JTA對(duì)DataSource、Connection和Resource 都是有要求的,只有符合XA規(guī)范,并且實(shí)現(xiàn)了XA規(guī)范的相關(guān)接口的類才能參與到JTA事務(wù)中來(lái),關(guān)于XA規(guī)范,請(qǐng)看我的另外一篇文章中有相關(guān)介紹。這里,提一句,目前主流的數(shù)據(jù)庫(kù)都支持XA規(guī)范。

要想使用用 JTA 事務(wù),那么就需要有一個(gè)實(shí)現(xiàn) javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC 驅(qū)動(dòng)程序。一個(gè)實(shí)現(xiàn)了這些接口的驅(qū)動(dòng)程序?qū)⒖梢詤⑴c JTA 事務(wù)。一個(gè) XADataSource 對(duì)象就是一個(gè) XAConnection 對(duì)象的工廠。XAConnection 是參與 JTA 事務(wù)的 JDBC 連接。

要使用JTA事務(wù),必須使用XADataSource來(lái)產(chǎn)生數(shù)據(jù)庫(kù)連接,產(chǎn)生的連接為一個(gè)XA連接。

XA連接(javax.sql.XAConnection)和非XA(java.sql.Connection)連接的區(qū)別在于:XA可以參與JTA的事務(wù),而且不支持自動(dòng)提交。

示例代碼:

public void JtaTransfer() {  
    javax.transaction.UserTransaction tx = null; 
    java.sql.Connection conn = null; 
     try{  
       tx = (javax.transaction.UserTransaction) context.lookup("java:comp/UserTransaction"); //取得JTA事務(wù),本例中是由Jboss容器管理 
       javax.sql.DataSource ds = (javax.sql.DataSource) context.lookup("java:/XAOracleDS"); //取得數(shù)據(jù)庫(kù)連接池,必須有支持XA的數(shù)據(jù)庫(kù)、驅(qū)動(dòng)程序  
       tx.begin(); 
      conn = ds.getConnection(); 
 
       // 將自動(dòng)提交設(shè)置為 false, 
       //若設(shè)置為 true 則數(shù)據(jù)庫(kù)將會(huì)把每一次數(shù)據(jù)更新認(rèn)定為一個(gè)事務(wù)并自動(dòng)提交 
       conn.setAutoCommit(false); 
 
       stmt = conn.createStatement();  
       // 將 A 賬戶中的金額減少 500  
       stmt.execute("\ 
       update t_account set amount = amount - 500 where account_id = 'A'"); 
       // 將 B 賬戶中的金額增加 500  
       stmt.execute("\ 
       update t_account set amount = amount + 500 where account_id = 'B'"); 
 
       // 提交事務(wù) 
       tx.commit(); 
       // 事務(wù)提交:轉(zhuǎn)賬的兩步操作同時(shí)成功 
     } catch(SQLException sqle){       
       try{  
         // 發(fā)生異常,回滾在本事務(wù)中的操做 
       tx.rollback(); 
         // 事務(wù)回滾:轉(zhuǎn)賬的兩步操作完全撤銷 
         stmt.close();  
         conn.close();  
       }catch(Exception ignore){  
 
       }  
       sqle.printStackTrace();  
     }  
   } 

上面的例子就是一個(gè)使用JTA事務(wù)的轉(zhuǎn)賬操作,該操作相對(duì)依賴于J2EE容器,并且需要通過(guò)JNDI的方式獲取UserTransaction和Connection。

標(biāo)準(zhǔn)的分布式事務(wù)

一個(gè)分布式事務(wù)(Distributed Transaction)包括一個(gè)事務(wù)管理器(transaction manager)和一個(gè)或多個(gè)資源管理器(resource manager)。一個(gè)資源管理器(resource manager)是任意類型的持久化數(shù)據(jù)存儲(chǔ)。事務(wù)管理器(transaction manager)承擔(dān)著所有事務(wù)參與單元者的相互通訊的責(zé)任。

看上面關(guān)于分布式事務(wù)的介紹是不是和2PC中的事務(wù)管理比較像?的卻,2PC其實(shí)就是符合XA規(guī)范的事務(wù)管理器協(xié)調(diào)多個(gè)資源管理器的一種實(shí)現(xiàn)方式。 我之前有幾篇文章關(guān)于2PC和3PC的,那幾篇文章中介紹過(guò)分布式事務(wù)中的事務(wù)管理器是如何協(xié)調(diào)多個(gè)事務(wù)的統(tǒng)一提交或回滾的,后面我還會(huì)有幾篇文章詳細(xì)的介紹一下和分布式事務(wù)相關(guān)的內(nèi)容,包括但不限于全局事務(wù)、DTP模型、柔性事務(wù)等。

JTA的優(yōu)缺點(diǎn)

JTA的優(yōu)點(diǎn)很明顯,就是提供了分布式事務(wù)的解決方案,嚴(yán)格的ACID。但是,標(biāo)準(zhǔn)的JTA方式的事務(wù)管理在日常開(kāi)發(fā)中并不常用,因?yàn)樗泻芏嗳秉c(diǎn):

實(shí)現(xiàn)復(fù)雜

通常情況下,JTA UserTransaction需要從JNDI獲取。這意味著,如果我們使用JTA,就需要同時(shí)使用JTA和JNDI。
JTA本身就是個(gè)笨重的API。
通常JTA只能在應(yīng)用服務(wù)器環(huán)境下使用,因此使用JTA會(huì)限制代碼的復(fù)用性。

總結(jié)

Java事務(wù)的類型有三種:JDBC事務(wù)、JTA(Java Transaction API)事務(wù)、容器事務(wù),其中JDBC的事務(wù)操作用法比較簡(jiǎn)單,適合于處理同一個(gè)數(shù)據(jù)源的操作。JTA事務(wù)相對(duì)復(fù)雜,可以用于處理跨多個(gè)數(shù)據(jù)庫(kù)的事務(wù),是分布式事務(wù)的一種解決方案。

這里還要簡(jiǎn)單說(shuō)一下,雖然JTA事務(wù)是Java提供的可用于分布式事務(wù)的一套API,但是不同的J2EE平臺(tái)的實(shí)現(xiàn)都不一樣,并且都不是很方便使用,所以,一般在項(xiàng)目中不太使用這種較為負(fù)責(zé)的API?,F(xiàn)在業(yè)內(nèi)比較常用的分布式事務(wù)解決方案主要有異步消息確保型、TCC、最大努力通知等。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring Boot Admin監(jiān)控服務(wù)如何使用

    Spring Boot Admin監(jiān)控服務(wù)如何使用

    這篇文章主要介紹了Spring Boot Admin監(jiān)控服務(wù)如何使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Java動(dòng)態(tài)代理詳解及實(shí)例

    Java動(dòng)態(tài)代理詳解及實(shí)例

    這篇文章主要介紹了Java動(dòng)態(tài)代理詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • java開(kāi)發(fā)實(shí)現(xiàn)五子棋游戲

    java開(kāi)發(fā)實(shí)現(xiàn)五子棋游戲

    這篇文章主要為大家詳細(xì)介紹了java開(kāi)發(fā)實(shí)現(xiàn)五子棋游戲,具有雙人對(duì)戰(zhàn)和人機(jī)對(duì)戰(zhàn)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • MyBatis動(dòng)態(tài)SQL如何實(shí)現(xiàn)前端指定返回字段

    MyBatis動(dòng)態(tài)SQL如何實(shí)現(xiàn)前端指定返回字段

    這篇文章主要介紹了MyBatis動(dòng)態(tài)SQL如何實(shí)現(xiàn)前端指定返回字段,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 可視化Swing中JTable控件綁定SQL數(shù)據(jù)源的兩種方法深入解析

    可視化Swing中JTable控件綁定SQL數(shù)據(jù)源的兩種方法深入解析

    以下是對(duì)可視化Swing中JTable控件綁定SQL數(shù)據(jù)源的兩種方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考一下
    2013-07-07
  • Java中的snowflake算法詳解

    Java中的snowflake算法詳解

    這篇文章主要介紹了Java中的snowflake算法詳解,Snowflake算法產(chǎn)生是為了滿足Twitter每秒上萬(wàn)條消息的請(qǐng)求,每條消息都必須分配一條唯一的id,這些id還需要一些大致的順序,并且在分布式系統(tǒng)中不同機(jī)器產(chǎn)生的id必須不同,需要的朋友可以參考下
    2023-08-08
  • Java自定義比較器實(shí)現(xiàn)中文排序

    Java自定義比較器實(shí)現(xiàn)中文排序

    這篇文章主要介紹了Java自定義比較器實(shí)現(xiàn)中文排序,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • 解決Java中socket使用getInputStream()阻塞問(wèn)題

    解決Java中socket使用getInputStream()阻塞問(wèn)題

    這篇文章主要介紹了解決Java中socket使用getInputStream()阻塞問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • sun?unsafe類功能及使用注意事項(xiàng)詳解

    sun?unsafe類功能及使用注意事項(xiàng)詳解

    這篇文章主要為大家介紹了unsafe類的功能及在使用中需要注意的事項(xiàng)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-01-01
  • 在Map中實(shí)現(xiàn)key唯一不重復(fù)操作

    在Map中實(shí)現(xiàn)key唯一不重復(fù)操作

    這篇文章主要介紹了在Map中實(shí)現(xiàn)key唯一不重復(fù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評(píng)論

通化市| 鹤山市| 康马县| 苏尼特右旗| 阜康市| 云梦县| 荥经县| 兴隆县| 调兵山市| 江油市| 荥经县| 青海省| 邓州市| 兴安县| 喜德县| 孝感市| 常宁市| 东方市| 会昌县| 黑水县| 社旗县| 丰顺县| 宜宾市| 老河口市| 荆州市| 徐水县| 呈贡县| 乐安县| 芮城县| 黔西县| 石门县| 阿克苏市| 台南县| 平安县| 咸宁市| 英山县| 工布江达县| 黔南| 河津市| 增城市| 延川县|