一Spring事務(wù)的種類
1.聲明式事務(wù)
2.編程式事務(wù)
二Spring事務(wù)的具體描述
(一)聲明式事務(wù)
1.聲明式事務(wù)概述
SPRING事務(wù)處理模塊是通過(guò)AOP的功能來(lái)實(shí)現(xiàn)聲明式事務(wù)處理的。因此蝇狼,在SPRING事務(wù)處理中蜜唾,可以通過(guò)設(shè)計(jì)一個(gè)TransactionProxyFactoryBean來(lái)使用AOP功能署咽,通過(guò)這個(gè)TransactionProxyFactoryBean以生成代理對(duì)象往产,在這個(gè)代理對(duì)象中哟旗,通過(guò)TransactionInterceptor來(lái)完成對(duì)代理方法的攔截碟联,正是這些AOP的攔截功能脑豹,將事務(wù)處理的功能編織了進(jìn)來(lái)抗愁。在Spring的事務(wù)處理中馁蒂,在實(shí)現(xiàn)聲明式事務(wù)處理時(shí)呵晚,這是AOP和IOC模塊集成的部分。因此沫屡,在SPRING的事務(wù)處理中饵隙,對(duì)主要的事務(wù)實(shí)現(xiàn)做了一個(gè)抽象和適配。適配的具體事務(wù)處理器包括:對(duì)DATASOURCE數(shù)據(jù)源的事務(wù)處理支持沮脖,對(duì)Hibernate數(shù)據(jù)源的事務(wù)處理支持金矛,對(duì)JDO數(shù)據(jù)源的事務(wù)處理支持奠宜,對(duì)JPA和JTA等數(shù)據(jù)源的事務(wù)處理支持腹尖。這一系列的事務(wù)處理支持淌山,都是通過(guò)設(shè)計(jì)PlatformTransactionManager闭树、AbstractPlatformTransactionManager以及一系列的具體事務(wù)處理器來(lái)實(shí)現(xiàn)的贵少,而PlatformTransactionManager又實(shí)現(xiàn)了TransactionInterceptor接口岖是,通過(guò)這樣一個(gè)接口實(shí)現(xiàn)設(shè)計(jì)运准,就把這一系列的事務(wù)處理實(shí)現(xiàn)與TransactionProxyFactoryBean結(jié)合了起來(lái)涩堤,從而形成了spring聲明式事務(wù)處理的設(shè)計(jì)體系胚膊。
2.設(shè)計(jì)原理與基本過(guò)程
聲明式事務(wù)的實(shí)現(xiàn)大致可以分為以下的幾個(gè)部分:
1)讀取和處理IOC容器中配置的事務(wù)處理屬性故俐,并轉(zhuǎn)化為Spring事務(wù)處理需要的內(nèi)部數(shù)據(jù)結(jié)構(gòu)。具體來(lái)說(shuō)紊婉,這里涉及到的類是TransactionAttributrSourceAdvisor药版,從名字可以看出,它是一個(gè)AOP通知器喻犁,SPRING使用這個(gè)通知器來(lái)完成對(duì)事務(wù)處理屬性的處理槽片。處理的結(jié)果是,在IOC容器中配置的事務(wù)屬性信息株汉,會(huì)被讀入并轉(zhuǎn)化為TransactionAttribute表示的數(shù)據(jù)對(duì)象筐乳,這個(gè)數(shù)據(jù)對(duì)象是Spring對(duì)事務(wù)處理屬性值的數(shù)據(jù)抽象,對(duì)這些屬性的處理時(shí)和TransactionProxyFactoryBean攔截下來(lái)的事務(wù)方法的處理結(jié)合起來(lái)的乔妈。
2)Spring事務(wù)處理模塊的實(shí)現(xiàn)統(tǒng)一的事務(wù)處理過(guò)程蝙云。這個(gè)通用的事務(wù)處理過(guò)程包含處理事務(wù)配置屬性,以及與線程綁定完成事務(wù)處理過(guò)程路召,Spring通過(guò)TransactionInfo和TransactionStatus這兩個(gè)數(shù)據(jù)對(duì)象勃刨,在事務(wù)處理中記錄和傳遞相關(guān)的執(zhí)行場(chǎng)景。
3)底層的事務(wù)處理實(shí)現(xiàn)股淡。
(二)編程式事務(wù)
1.編程式事務(wù)設(shè)計(jì)原理
在編程式事務(wù)處理的過(guò)程中身隐,利用DefaultTransactionDefinition對(duì)象來(lái)持有事務(wù)處理實(shí)現(xiàn)。同時(shí)唯灵,在創(chuàng)建事務(wù)的過(guò)程中得到一個(gè)TransactionStatus對(duì)象贾铝,然后通過(guò)直接調(diào)用transactionManager的commit()和rollback()方法來(lái)完成事務(wù)。編程式事務(wù)與聲明式事務(wù)處理的實(shí)現(xiàn)是一致的。
三Spring事務(wù)的具體參數(shù)解釋
readOnly
事務(wù)屬性中的readOnly標(biāo)志表示對(duì)應(yīng)的事務(wù)應(yīng)該被最優(yōu)化為只讀事務(wù)垢揩。如果值為true就會(huì)告訴Spring我這個(gè)方法里面沒(méi)有insert或者update玖绿,你只需要提供只讀的數(shù)據(jù)庫(kù)Connection就行了,這種執(zhí)行效率會(huì)比read-write的Connection高叁巨,所以這是一個(gè)最優(yōu)化提示斑匪。在一些情況下,一些事務(wù)策略能夠起到顯著的最優(yōu)化效果锋勺,例如在使用Object/Relational映射工具(如:Hibernate或TopLink)時(shí)避免dirty checking(試圖“刷新”)蚀瘸。
timeout
在屬性中還有定義“timeout”值的選項(xiàng),指定事務(wù)超時(shí)為幾秒庶橱。一般不會(huì)使用這個(gè)屬性贮勃。在JTA中,這將被簡(jiǎn)單地傳遞到J2EE服務(wù)器的事務(wù)協(xié)調(diào)程序悬包,并據(jù)此得到相應(yīng)的解釋衙猪。
1.Isolation Level(事務(wù)隔離等級(jí))的5個(gè)枚舉值
為什么事務(wù)要有Isolation Level這個(gè)屬性?先回顧下數(shù)據(jù)庫(kù)事務(wù)的知識(shí):
第一類丟失更新(lost update):在完全未隔離事務(wù)的情況下布近,兩個(gè)事物更新同一條數(shù)據(jù)資源垫释,某一事物異常終止,回滾造成第一個(gè)完成的更新也同時(shí)丟失撑瞧。
第二類丟失更新(second lost updates):是不可重復(fù)讀的特殊情況棵譬,如果兩個(gè)事務(wù)都讀取同一行,然后兩個(gè)都進(jìn)行寫操作预伺,并提交订咸,第一個(gè)事務(wù)所做的改變就會(huì)丟失。
臟讀(dirty read):如果第二個(gè)事務(wù)查詢到第一個(gè)事務(wù)還未提交的更新數(shù)據(jù)酬诀,形成臟讀脏嚷。因?yàn)榈谝粋€(gè)事務(wù)你還不知道是否提交,所以數(shù)據(jù)不一定是正確的瞒御。
虛讀(phantom read):一個(gè)事務(wù)執(zhí)行兩次查詢父叙,第二次結(jié)果集包含第一次中沒(méi)有或者某些行已被刪除,造成兩次結(jié)果不一致肴裙,只是另一個(gè)事務(wù)在這兩次查詢中間插入或者刪除了數(shù)據(jù)造成的趾唱。
不可重復(fù)讀(unrepeated read):一個(gè)事務(wù)兩次讀取同一行數(shù)據(jù),結(jié)果得到不同狀態(tài)結(jié)果蜻懦,如中間正好另一個(gè)事務(wù)更新了該數(shù)據(jù)甜癞,兩次結(jié)果相異,不可信任宛乃。
當(dāng)遇到以上這些情況時(shí)我們可以設(shè)置isolation下面這些枚舉值(事務(wù)的隔離級(jí)別):
DEFAULT:采用數(shù)據(jù)庫(kù)默認(rèn)隔離級(jí)別
SERIALIZABLE:最嚴(yán)格的級(jí)別悠咱,事務(wù)串行執(zhí)行蒸辆,資源消耗最大;
REPEATABLE_READ:保證了一個(gè)事務(wù)不會(huì)修改已經(jīng)由另一個(gè)事務(wù)讀取但未提交(回滾)的數(shù)據(jù)乔煞。避免了“臟讀取”和“不可重復(fù)讀取”的情況吁朦,但是帶來(lái)了更多的性能損失柒室。
READ_COMMITTED:大多數(shù)主流數(shù)據(jù)庫(kù)的默認(rèn)事務(wù)等級(jí)渡贾,保證了一個(gè)事務(wù)不會(huì)讀到另一個(gè)并行事務(wù)已修改但未提交的數(shù)據(jù),避免了“臟讀取”雄右。該級(jí)別適用于大多數(shù)系統(tǒng)空骚。
READ_UNCOMMITTED:保證了讀取過(guò)程中不會(huì)讀取到非法數(shù)據(jù)。隔離級(jí)別在于處理多事務(wù)的并發(fā)問(wèn)題擂仍。
2.關(guān)于propagation屬性的7個(gè)傳播行為
REQUIRED:指定當(dāng)前方法必需在事務(wù)環(huán)境中運(yùn)行囤屹,如果當(dāng)前有事務(wù)環(huán)境就加入當(dāng)前正在執(zhí)行的事務(wù)環(huán)境,如果當(dāng)前沒(méi)有事務(wù)逢渔,就新建一個(gè)事務(wù)肋坚。這是默認(rèn)值。
SUPPORTS:指定當(dāng)前方法加入當(dāng)前事務(wù)環(huán)境肃廓,如果當(dāng)前沒(méi)有事務(wù)智厌,就以非事務(wù)方式執(zhí)行。
MANDATORY:指定當(dāng)前方法必須加入當(dāng)前事務(wù)環(huán)境盲赊,如果當(dāng)前沒(méi)有事務(wù)铣鹏,就拋出異常。
REQUIRES_NEW:指定當(dāng)前方法總是會(huì)為自己發(fā)起一個(gè)新的事務(wù)哀蘑,如果發(fā)現(xiàn)當(dāng)前方法已運(yùn)行在一個(gè)事務(wù)中,則原有事務(wù)被掛起,我自己創(chuàng)建一個(gè)屬于自己的事務(wù),直我自己這個(gè)方法commit結(jié)束,原先的事務(wù)才會(huì)恢復(fù)執(zhí)行诚卸。
NOT_SUPPORTED:指定當(dāng)前方法以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù)绘迁,就把當(dāng)前事務(wù)掛起合溺,等我以非事務(wù)的狀態(tài)運(yùn)行完,再繼續(xù)原來(lái)的事務(wù)缀台。
NEVER:指定當(dāng)前方法絕對(duì)不能在事務(wù)范圍內(nèi)執(zhí)行棠赛,如果方法在某個(gè)事務(wù)范圍內(nèi)執(zhí)行,容器就拋異常将硝,只有沒(méi)關(guān)聯(lián)到事務(wù)恭朗,才正常執(zhí)行。
NESTED:指定當(dāng)前方法執(zhí)行時(shí)依疼,如果已經(jīng)有一個(gè)事務(wù)存在,則運(yùn)行在這個(gè)嵌套的事務(wù)中.如果當(dāng)前環(huán)境沒(méi)有運(yùn)行的事務(wù)痰腮,就新建一個(gè)事務(wù),并與父事務(wù)相互獨(dú)立律罢,這個(gè)事務(wù)擁有多個(gè)可以回滾的保證點(diǎn)膀值。就是指我自己內(nèi)部事務(wù)回滾不會(huì)對(duì)外部事務(wù)造成影響棍丐,只是針對(duì)DataSourceTransactionManager事務(wù)管理器起效。