Spring事務的傳播特性

前言:

? ? Spring的事務纫骑,也就是數(shù)據(jù)庫的事務操作蒙袍,符合ACID標準,也具有標準的事務隔離級別。

? ? 但是Spring事務有自己的特點细移,也就是事務傳播機制澈吨。

? ??所謂事務傳播機制宛蚓,也就是在事務在多個方法的調用中是如何傳遞的斜姥,是重新創(chuàng)建事務還是使用父方法的事務?父方法的回滾對子方法的事務是否有影響武花?這些都是可以通過事務傳播機制來決定的圆凰。

? ? 本文就測試一下這些事務傳播機制的使用及異同

1.準備測試方法

? ? 主要是創(chuàng)建兩個service接口(接口主要是對數(shù)據(jù)庫表的操作),并創(chuàng)建其實現(xiàn)類

1)創(chuàng)建beans.xml体箕,開啟事務


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx"

xsi:schemaLocation="

? ? ? ? http://www.springframework.org/schema/beans

? ? ? ? http://www.springframework.org/schema/beans/spring-beans.xsd

? ? ? ? http://www.springframework.org/schema/tx

? ? ? ? http://www.springframework.org/schema/tx/spring-tx.xsd

? ? ? ? http://www.springframework.org/schema/aop

? ? ? ? http://www.springframework.org/schema/aop/spring-aop.xsd">

</beans>

?? 2)創(chuàng)建實體類和表(表創(chuàng)建讀者可自定義創(chuàng)建)

@Data

@AllArgsConstructor

@NoArgsConstructor

publicclassBlog{

privateintid;

privateString name;

privateString ur;

}

? ? 3)創(chuàng)建service接口(BlogService和BlogService2专钉,主要是對Blog的不同操作)

// BlogService

packagejdbc;

// 主要負責Blog的添加和修改

publicinterfaceBlogService{

voidsave(Blog blog);

voidupdate(Blog blog);

}

// BlogService2

packagejdbc;

// 主要負責Blog的刪除

publicinterfaceBlogService2{

voiddelete(intid);

}

?4)創(chuàng)建其實現(xiàn)類(BlogServiceImpl,BlogService2)

BlogServiceImpl.java

@Transactional(propagation=Propagation.REQUIRED)

@Component

publicclassBlogServiceImplimplementsBlogService{

@Autowired

privateJdbcTemplate jdbcTemplate;

@Autowired

privateBlogService2 blogService2;

@Override

publicvoidsave(Blog blog){

String sql ="insert into blog values(?,?,?)";

jdbcTemplate.update(sql,

newObject[]{blog.getId(),blog.getName(),blog.getUr()},

newint[]{java.sql.Types.INTEGER,java.sql.Types.VARCHAR,java.sql.Types.VARCHAR});

blogService2.delete(16);

// update(blog);

// throw new RuntimeException("error");

}

@Override

publicvoidupdate(Blog blog){

String sql ="update blog set name = ? where id=?";

jdbcTemplate.update(sql,newObject[]{blog.getName(),blog.getId()},

newint[]{java.sql.Types.VARCHAR,java.sql.Types.INTEGER});

}

}

BlogService2.java

@Transactional(propagation=Propagation.REQUIRED)

@Component

publicclassBlogServiceImpl2implementsBlogService2{

@Autowired

privateJdbcTemplate jdbcTemplate;

@Override

publicvoiddelete(intid){

String sql ="delete from blog where id=?";

jdbcTemplate.update(sql, id);

}

}

? ? 注意:既然要實現(xiàn)多事務的傳播累铅,就需要在一個方法里調用另一個類的方法跃须,下面的測試就是基于這種方法,在BlogService的save()方法中調用BlogService2的delete()方法


? ? 5)創(chuàng)建Configuration類娃兽,用于創(chuàng)建DataSource實現(xiàn)

@Configuration

@ComponentScan(basePackages={"jdbc"})// 掃描BlogService實現(xiàn)類所在的包路徑

@ImportResource(locations={"classpath:beans.xml"})// 添加事務管理

publicclassJdbcConfig{

@Bean

publicJdbcTemplatejdbcTemplate(DataSource dataSource){

returnnewJdbcTemplate(dataSource);

}

@Bean

publicDataSourceTransactionManagertransactionManager(DataSource dataSource){

returnnewDataSourceTransactionManager(dataSource);

}

@Bean

publicDataSourcedataSource(){

try{

returnnewSimpleDriverDataSource(newcom.mysql.jdbc.Driver(),"jdbc:mysql://localhost:3306/test","root","root");

}catch(SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

returnnull;

}

6)測試

publicclassTest{

publicstaticvoidmain(String[] args){

AnnotationConfigApplicationContext ac =newAnnotationConfigApplicationContext(JdbcConfig.class);

BlogService service = ac.getBean(BlogService.class);

Blog b =newBlog(18,"lili","url");

service.save(b);

}

}

總結:大體的測試框架就如上所示菇民,下面的測試修改主要是修改BlogServiceImpl和BlogServiceImpl2的事務傳播機制@Transactional(propagation=Propagation.REQUIRED)



3.事務傳播機制的測試


? ? 1)REQUIRED

定義:如果有事務則加入事務,如果沒有事務投储,則創(chuàng)建一個新的(默認值)

操作1:將BlogServiceImpl和BlogServiceImpl2的事務傳播機制都修改為

@Transactional(propagation=Propagation.REQUIRED)

?結果1

操作2:將BlogServiceImpl事務傳播機制修改為@Transactional(propagation=Propagation.NOT_SUPPORTED)第练,BlogServiceImpl2的仍為@Transactional(propagation=Propagation.REQUIRED)

結果2:

總結:

? ??? ??當BlogServiceImpl提供事務的時候,BlogServiceImpl2的方法執(zhí)行使用當前已有事務玛荞,不再新建事務娇掏;

如果出現(xiàn)異常則全部回滾;

? ? ? ? 當BlogServiceImpl不創(chuàng)建事務的時候勋眯,BlogServiceImpl2的方法執(zhí)行發(fā)現(xiàn)沒有事務可用婴梧,自己新建事務壁涎;

2)NOT_SUPPORTED

定義:Spring不為當前方法開啟事務,相當于沒有事務

? ? 操作:將BlogServiceImpl和BlogServiceImpl2的事務傳播機制都

修改為@Transactional(propagation=Propagation.NOT_SUPPORTED)

結果:

總結:

? ? ? ? NOT_SUPPORTED相當于沒有Spring事務志秃,每條執(zhí)行語句單獨執(zhí)行,單獨提交

3)REQUIRES_NEW

定義:不管是否存在事務嚼酝,都創(chuàng)建一個新的事務浮还,原來的方法掛起,新的方法執(zhí)行完畢后闽巩,繼續(xù)執(zhí)行老的事務

操作:將BlogServiceImpl事務傳播機制修改為@Transactional(propagation=Propagation.REQUIRED)钧舌,BlogServiceImpl2的仍為@Transactional(propagation=Propagation.REQUIRES_NEW)

結果:

? ? 總結:

? ? ? ? REQUIRES_NEW為當前方法創(chuàng)建一個新的事務,并且當前事務先提交涎跨,然后再提交老的事務

4)MANDATORY

定義:必須在一個已有的事務中執(zhí)行洼冻,否則報錯

操作:將BlogServiceImpl事務傳播機制修改為@Transactional(propagation=Propagation.NOT_SUPPORTED),BlogServiceImpl2的仍為@Transactional(propagation=Propagation.MANDATORY)隅很,查看是否報錯

? 結果:

? ? 總結:? ??

? ? ? ? MANDATORY必須在已有事務下被調用撞牢,否則報錯

? ? ? ? NOT_SUPPORTED執(zhí)行數(shù)據(jù)庫層面的事務操作,故當前測試中叔营,insert方法成功執(zhí)行屋彪,delete方法的拋錯并不影響insert方法的執(zhí)行

5)NEVER

? ? 定義:必須在一個沒有的事務中執(zhí)行,否則報錯

操作:將BlogServiceImpl事務傳播機制修改為@Transactional(propagation=Propagation.REQUIRED)绒尊,BlogServiceImpl2的仍為@Transactional(propagation=Propagation.MANDATORY)畜挥,查看是否報錯

? 結果:

? ? 總結:

? ? ? ? NEVER必須在沒有事務的方法中執(zhí)行,否則報錯婴谱;

? ? ? ? save方法開啟一個事務蟹但,還沒來及提交發(fā)現(xiàn)delete方法報錯,只能回滾事務

? 6)SUPPORTS

定義:如果其他bean調用這個方法時谭羔,其他bean聲明了事務华糖,則就用這個事務,如果沒有聲明事務口糕,那就不用事務

操作1:將BlogServiceImpl事務傳播機制修改為@Transactional(propagation=Propagation.REQUIRED)缅阳,BlogServiceImpl2的仍為@Transactional(propagation=Propagation.SUPPORTS)

結果1:

操作1:將BlogServiceImpl事務傳播機制修改為@Transactional(propagation=Propagation.NOT_SUPPORTED),BlogServiceImpl2的仍為@Transactional(propagation=Propagation.SUPPORTS)

結果1:

? ??總結:

? ? ? ? SUPPORTS類型的事務傳播機制景描,是否使用事務取決于調用方法是否有事務十办,如果有則直接用,如果沒有則不使用事務

7)NESTED

定義:如果當前存在事務超棺,則在嵌套事務內執(zhí)行向族。如果當前沒有事務,則執(zhí)行與REQUIRED類似的操作

操作1:將BlogServiceImpl事務傳播機制修改為@Transactional(propagation=Propagation.REQUIRED)棠绘,BlogServiceImpl2的仍為@Transactional(propagation=Propagation.NESTED)

?結果1:

操作2:將BlogServiceImpl事務傳播機制修改為@Transactional(propagation=Propagation.NOT_SUPPORTED)件相,BlogServiceImpl2的仍為@Transactional(propagation=Propagation.NESTED)

?結果2:

? ? 總結:

? ? ? ? save方法創(chuàng)建一個事務再扭,則再調用delete方法時,直接在該事務的基礎上創(chuàng)建一個嵌套事務夜矗,本質上還是同一個事務泛范,做一次提交;

? ? ? ? save方法不創(chuàng)建事務紊撕,則調用delete方法時罢荡,直接創(chuàng)建一個新的事務,單獨提交

4.注意事項


1)REQUIRED

? ? ? ? 當兩個方法的傳播機制都是REQUIRED時对扶,如果一旦發(fā)生回滾区赵,兩個方法都會回滾


? 2)REQUIRES_NEW

? ? ? ? 當delete方法傳播機制為REQUIRES_NEW,會開啟一個新的事務浪南,并單獨提交方法笼才,所以save方法的回滾并不影響delete方法事務提交


? 3)NESTED

? ? ? ? 當save方法為REQUIRED,delete方法為NESTED時络凿,delete方法開啟一個嵌套事務骡送;

? ? ? ? 當save方法回滾時,delete方法也會回滾絮记;反之各谚,如果delete方法回滾,則并不影響save方法的提交

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末到千,一起剝皮案震驚了整個濱河市昌渤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌憔四,老刑警劉巖膀息,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異了赵,居然都是意外死亡潜支,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門柿汛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來冗酿,“玉大人,你說我怎么就攤上這事络断〔锰妫” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵貌笨,是天一觀的道長弱判。 經常有香客問我,道長锥惋,這世上最難降的妖魔是什么昌腰? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任开伏,我火速辦了婚禮,結果婚禮上遭商,老公的妹妹穿的比我還像新娘固灵。我一直安慰自己,他們只是感情好劫流,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布怎虫。 她就那樣靜靜地躺著,像睡著了一般困介。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蘸际,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天座哩,我揣著相機與錄音,去河邊找鬼粮彤。 笑死根穷,一個胖子當著我的面吹牛,可吹牛的內容都是我干的导坟。 我是一名探鬼主播屿良,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼惫周!你這毒婦竟也來了尘惧?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤递递,失蹤者是張志新(化名)和其女友劉穎喷橙,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體登舞,經...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡贰逾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了菠秒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疙剑。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖践叠,靈堂內的尸體忽然破棺而出言缤,到底是詐尸還是另有隱情,我是刑警寧澤禁灼,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布轧简,位于F島的核電站,受9級特大地震影響匾二,放射性物質發(fā)生泄漏哮独。R本人自食惡果不足惜拳芙,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望皮璧。 院中可真熱鬧舟扎,春花似錦、人聲如沸悴务。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讯檐。三九已至羡疗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間别洪,已是汗流浹背叨恨。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留挖垛,地道東北人痒钝。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像痢毒,于是被迫代替她去往敵國和親送矩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內容