程序猿基礎(chǔ)知識的學(xué)習(xí)厨剪、理解哄酝、整理——事務(wù)(方方土)
事務(wù),看似很簡單祷膳,其實很復(fù)雜陶衅,作為一個程序猿,你對事務(wù)到底了解多少直晨。下面主要以一個JAVA程序猿的角度來闡述一下事務(wù)搀军。以下內(nèi)容主要是讀書《java事務(wù)設(shè)計策略》的筆記以及基于平時一些認知的總結(jié),非原創(chuàng)S禄省罩句!^_^,還有“簡書”真實不錯敛摘,很好的一個工具门烂,推薦使用
什么是事務(wù)?ACID(原子性兄淫、一致性屯远、獨立性、持久化)
什么是事務(wù)模型咖气?這里提到的事務(wù)模型主要是闡述的是怎么樣來管理事務(wù)的概念。分為以下三種事務(wù)模式:本地事務(wù)模型挖滤,編程式事務(wù)模型崩溪,聲明式事務(wù)模型
為什么要提事務(wù)模型這個概念,其實本質(zhì)上事務(wù)模型也就是一個抽象的概念斩松,主要體現(xiàn)的是開發(fā)人員在不同的場景下伶唯,用不同的方法來實現(xiàn)事務(wù)的管理,從以下內(nèi)容的描述惧盹,希望可以叫直觀地表達了這些事務(wù)模型的不同點乳幸,這些事務(wù)模型的優(yōu)缺點點。
從我的編程習(xí)慣來說钧椰,經(jīng)歷過本地事務(wù)模型的階段粹断,經(jīng)歷過編程式事務(wù)模型的階段,到現(xiàn)在基本上使用聲明式的事務(wù)模型嫡霞,我感覺這三種方式是不斷進化的過程瓶埋。用過才知道,哪個好。就好比大家現(xiàn)在都用spring养筒,都說spring好曾撤,那它究竟好在哪里呢?究竟解決了些什么問題呢晕粪?只有比較才知道挤悉。
- 直觀感受一下什么叫“本地事務(wù)模型”
public void update TradeOrder(TradeOrderDate order)
throws Exception{
DataSource ds = (DataSource)
(new InitialContext()).lookup("jdbc/MasterDS");
conn = ds.getConnection();
conn.setAutoCommit(false);
Statement stmt ?= conn.createStatement();
String sql = "update trade_order ....";
try{
stmt.excuteUpdate(sql);
conn.commit();
}catch(Exception e){
conn.rollback();
throws e;
}finally{
stmt.close;
conn.close;
}
}
很簡單的一個jdbc操作的一個函數(shù),就在這個函數(shù)中包含了本地事務(wù)模型的概念尚氛,標粗部分衅斩,其實在這個函數(shù)中,對于開發(fā)人員而言怠褐,獲取的是一個數(shù)據(jù)庫的連接conn畏梆,而不是一個事務(wù),所以在這個函數(shù)中奈懒,對于開發(fā)人員而言奠涌,沒有事務(wù)的操作,事務(wù)是通過conn委托給數(shù)據(jù)庫去操作的磷杏;
- “本地事務(wù)模型”存在什么問題
1溜畅、對于開發(fā)人員的侵入性較大,開發(fā)人員在編碼的時候极祸,時刻要想著commit慈格,commit,commit遥金,且都是一些重復(fù)代碼浴捆;
2、如果涉及兩個方法調(diào)用稿械,比如有方法A选泻,調(diào)用方法B和方法C,大家想想美莫,如果采用本地事務(wù)模型页眯,那么這個時候的方法A還是一個事務(wù)嗎?所以厢呵,開發(fā)人員在設(shè)計的時候窝撵,要想的很清楚,到底有哪些方法
3襟铭、如果涉及到XA碌奉,比如一個方法中既有jdbc操作短曾,又有jms操作,該怎么辦呢道批?
4、所以入撒,如果是自己寫一個jdbc的小DEMO,那么可以用本地事務(wù)模型這種方式來玩玩隆豹,如果是在大型的系統(tǒng)建設(shè)中,就務(wù)必要杜絕茅逮。
- 直觀感受一下什么叫“編程式事務(wù)模型”
Public void updateTradeOrder(TradeOrderData order)
throws Exception{UserTransaction txn = sessionCtx.getUserTransaction();txn.begin();try{TradeOrderDao dao = new TraderOrderDao();dao.updateTradeOrder(order);txn.commit();}catch(Excption e){log.fatal(e);txn.rollback();throw e;}}很簡單的一個更新操作的一個函數(shù)碉考,就在這個函數(shù)中包含了編程式事務(wù)模型的概念,標粗部分挺身,其實在這個函數(shù)中侯谁,對于開發(fā)人員而言,獲取的是一個事務(wù)對象txn章钾,而不是一個數(shù)據(jù)庫連接墙贱,所以在這個函數(shù)中,對于開發(fā)人員而言贱傀,是通過txn來管理事務(wù)的惨撇;
- “編程式事務(wù)模型”存在什么問題
1、編程式事務(wù)府寒,事務(wù)的管理要由開發(fā)人員自己來管理魁衙,要考慮好事務(wù)提交,事務(wù)在異常情況下的處理等等事宜株搔,是一件比較繁瑣剖淀,容易出錯的事情
2、編程式事務(wù)的上下文傳遞問題纤房,什么是事務(wù)上下文傳遞呢祷蝌?舉例來說,方法A調(diào)用了方法B帆卓,(方法A和方法B都采用編程式的事務(wù)模型)巨朦,那么方法A中創(chuàng)建的事務(wù)無法傳遞到方法B中。大家想想看剑令,其實很多業(yè)務(wù)場景糊啡,在方法A調(diào)用方法B的這種場景下,我們都認為方法A整體是一個事務(wù)吁津,但是如果采用編程式事務(wù)模型棚蓄,那么它內(nèi)部本質(zhì)是兩個事務(wù)堕扶;
- 直觀感受一下什么叫“聲明式事務(wù)模型”
@TransactionAttribute(TransactionAttribute.Type.Required)
public void updateTradeOrder(TradeOrderData order)
throw Exception{try{TradeOrderDao dao = new TradeOrderDao();dao.updateTradeOrder(order);}catch (Exception e){sessionContext.setRollbackOnly();throw e;}}很簡單的一個操作稍算,大家發(fā)現(xiàn)在這個函數(shù)中,沒有用到連接役拴,也沒有看到事務(wù)糊探,而只是有一行注解,就是通過這行注解就將這個函數(shù)的失去托管給容器去管理了河闰。
- “聲明式事務(wù)模型中的事務(wù)屬性”
1科平、Required(需要一個事務(wù),如果上下文中已有事務(wù)姜性,則用之瞪慧,如沒有,則新建一個事務(wù)部念。說明上下文事務(wù)是傳遞的)
2弃酌、Mandatory(需要一個事務(wù),如果上下文中沒有事務(wù)儡炼,就報異常矢腻。說明上下文事務(wù)是傳遞的,而且必須要通過上下文事務(wù)的傳遞)
3射赛、RequiredNew(需要一個事務(wù)多柑,如果上下文中有事務(wù),將該事務(wù)掛起楣责,新開一個事務(wù)竣灌。說明上下文事務(wù)是不傳遞的)
4、Supports(不需要一個事務(wù)秆麸,如果上下文中有事務(wù)初嘹,則用之,如果沒有沮趣,則不用事務(wù))
5屯烦、NotSupported(不需要一個事務(wù),如果上下文中有事務(wù)房铭,則暫停事務(wù)驻龟,運行結(jié)束后,再開啟事務(wù))
6缸匪、Never(不需要一個事務(wù)翁狐,如果在上下文中有事務(wù),就報異常)
好凌蔬,到這里露懒,有兩個問題闯冷,需要大家去思考一下?
1懈词、到底我們的哪些方法需要事務(wù)蛇耀?哪些方法不需要事務(wù)?事務(wù)給我們帶來的開銷是什么坎弯?
2纺涤、在我們的程序中,事務(wù)到底要控制在哪里荞怒,控制在在DAO層洒琢,還是控制在Service層秧秉?為什么褐桌?