深入了解Spring的事務傳播機制_第1頁
深入了解Spring的事務傳播機制_第2頁
深入了解Spring的事務傳播機制_第3頁
深入了解Spring的事務傳播機制_第4頁
深入了解Spring的事務傳播機制_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

第深入了解Spring的事務傳播機制目錄Spring事務傳播機制有哪些?事務傳播機制使用與演示REQUIRED使用演示REQUIRED_NEW使用演示NESTED使用演示總結Spring事務傳播機制是指,包含多個事務的方法在相互調(diào)用時,事務是如何在這些方法間傳播的。

既然是事務傳播,所以事務的數(shù)量應該在兩個或兩個以上,Spring事務傳播機制的誕生是為了規(guī)定多個事務在傳播過程中的行為的。比如方法A開啟了事務,而在執(zhí)行過程中又調(diào)用了開啟事務的B方法,那么B方法的事務是應該加入到A事務當中呢?還是兩個事務相互執(zhí)行互不影響,又或者是將B事務嵌套到A事務中執(zhí)行呢?所以這個時候就需要一個機制來規(guī)定和約束這兩個事務的行為,這就是Spring事務傳播機制所解決的問題。

Spring事務傳播機制有哪些?

Spring事務傳播機制可使用@Transactional(propagation=Propagation.REQUIRED)來定義,Spring事務傳播機制的級別包含以下7種:

Propagation.REQUIRED:默認的事務傳播級別,它表示如果當前存在事務,則加入該事務;如果當前沒有事務,則創(chuàng)建一個新的事務。Propagation.SUPPORTS:如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續(xù)運行。Propagation.MANDATORY:(mandatory:強制性)如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出異常。Propagation.REQUIRES_NEW:表示創(chuàng)建一個新的事務,如果當前存在事務,則把當前事務掛起。也就是說不管外部方法是否開啟事務,Propagation.REQUIRES_NEW修飾的內(nèi)部方法會新開啟自己的事務,且開啟的事務相互獨立,互不干擾。Propagation.NOT_SUPPORTED:以非事務方式運行,如果當前存在事務,則把當前事務掛起。Propagation.NEVER:以非事務方式運行,如果當前存在事務,則拋出異常。Propagation.NESTED:如果當前存在事務,則創(chuàng)建一個事務作為當前事務的嵌套事務來運行;如果當前沒有事務,則該取值等價于PROPAGATION_REQUIRED。

以上7種傳播機制,可根據(jù)是否支持當前事務的維度分為以下3類:

看到這里,有人可能會說:說了這么多,我也看不懂啊,即使看懂了,我也記不住???這要咋整?

沒關系,接下來我們用一個例子,來說明這3類事務傳播機制的區(qū)別。

以情侶之間是否要買房為例,我們將以上3類事務傳播機制可以看作是戀愛中的3類女生類型:

普通型強勢型懂事型

這三類女生如下圖所示:

支持當前事務的女生,這里的事務指的是房子,它分為3種(普通型女生):

Propagation.REQUIRED(需要有房子):有房子了咱們一起住,沒房子了咱們一起賺錢買房子。Propagation.SUPPORTS(可以有房子):有房子了就一起住,沒房子了咱們就一起租房子。Propagation.MANDATORY(強制有房子):有房子了就一起住,沒房子了就分手。

不支持當前事務的女生也分為3種(強勢型或者叫事業(yè)型):

Propagation.REQUIRES_NEW:不要你的房子,必須一起賺錢買房子。Propagation.NOT_SUPPORTED:不要你的房子,必須一起租房子。Propagation.NEVER:必須一起租房子,你有房子就分手。

最后一種是嵌套性事務Propagation.NESTED,它屬于懂事型女友,如果有房子了就以房子為基礎做點小生意,賣個花生、水果啥的,如果買賣成了,那就繼續(xù)發(fā)展;如果失敗了,至少還有房子;如果沒房子也沒關系,一起賺錢買房子。

事務傳播機制使用與演示

接下來我們演示一下事務傳播機制的使用,以下面3個最典型的事務傳播級別為例:

支持當前事務的REQUIRED;不支持當前事務的REQUIRES_NEW;嵌套事務NESTED。

下來我們分別來看。

事務傳播機制的示例,需要用到以下兩張表:

--用戶表

CREATETABLE`user`(

`id`int(11)NOTNULLAUTO_INCREMENT,

`name`varchar(255)COLLATEutf8mb4_binDEFAULTNULL,

`password`varchar(255)COLLATEutf8mb4_binDEFAULTNULL,

`createtime`datetimeDEFAULTCURRENT_TIMESTAMP,

PRIMARYKEY(`id`)USINGBTREE

)ENGINE=InnoDBAUTO_INCREMENT=6DEFAULTCHARSET=utf8mb4COLLATE=utf8mb4_binROW_FORMAT=DYNAMIC;

--日志表

CREATETABLE`log`(

`id`int(11)NOTNULLAUTO_INCREMENT,

`content`textNULL,

PRIMARYKEY(`id`)

)ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COLLATE=utf8mb4_bin;

創(chuàng)建一個SpringBoot項目,核心業(yè)務代碼有3個:UserController、UserServcie以及LogService。在UserController里面調(diào)用UserService添加用戶,并調(diào)用LogService添加日志。

REQUIRED使用演示

REQUIRED支持當前事務。

UserController實現(xiàn)代碼如下,其中save方法開啟了事務:

@RestController

publicclassUserController{

@Resource

privateUserServiceuserService;

@Resource

privateLogServicelogService;

@RequestMapping("/save")

@Transactional

publicObjectsave(Useruser){

//插入用戶操作

userService.save(user);

//插入日志

logService.saveLog("用戶插入:"+user.getName());

returntrue;

UserService實現(xiàn)代碼如下:

@Service

publicclassUserService{

@Resource

privateUserMapperuserMapper;

@Transactional(propagation=Propagation.REQUIRED)

publicintsave(Useruser){

returnuserMapper.save(user);

LogService實現(xiàn)代碼如下:

@Service

publicclassLogService{

@Resource

privateLogMapperlogMapper;

@Transactional(propagation=Propagation.REQUIRED)

publicintsaveLog(Stringcontent){

//出現(xiàn)異常

inti=10/0;

returnlogMapper.saveLog(content);

執(zhí)行結果:程序報錯,兩張表中都沒有插入任何數(shù)據(jù)。

執(zhí)行流程描述:

首先UserService中的添加用戶方法正常執(zhí)行完成。LogService保存日志程序報錯,因為使用的是UserController中的全局事務,所以整個事務回滾,步驟1中的操作也跟著回滾。所以數(shù)據(jù)庫中沒有添加任何數(shù)據(jù)。

REQUIRED_NEW使用演示

REQUIRED_NEW不支持當前事務。

UserController實現(xiàn)代碼:

@RequestMapping("/save")

@Transactional

publicObjectsave(Useruser){

//插入用戶操作

userService.save(user);

//插入日志

logService.saveLog("用戶插入:"+user.getName());

returntrue;

UserService實現(xiàn)代碼:

@Service

publicclassUserService{

@Resource

privateUserMapperuserMapper;

@Transactional(propagation=Propagation.REQUIRES_NEW)

publicintsave(Useruser){

System.out.println("執(zhí)行save方法.");

returnuserMapper.save(user);

LogService實現(xiàn)代碼:

@Service

publicclassLogService{

@Resource

privateLogMapperlogMapper;

@Transactional(propagation=Propagation.REQUIRES_NEW)

publicintsaveLog(Stringcontent){

//出現(xiàn)異常

inti=10/0;

returnlogMapper.saveLog(content);

程序執(zhí)行結果:

User表中成功添加了一條用戶數(shù)據(jù),Log表執(zhí)行失敗,沒有加入任何數(shù)據(jù),但它并沒有影響到UserController中的事務執(zhí)行。

通過以上結果可以看出:LogService中使用的是單獨的事務,雖然LogService中的事務執(zhí)行失敗了,但并沒有影響UserController和UserService中的事務。

NESTED使用演示

NESTED是嵌套事務。

UserController實現(xiàn)代碼如下:

@RequestMapping("/save")

@Transactional

publicObjectsave(Useruser){

//插入用戶操作

userService.save(user);

returntrue;

UserService實現(xiàn)代碼如下:

@Transactional(propagation=Propagation.NESTED)

publicintsave(Useruser){

intresult=userMapper.save(user);

System.out.println("執(zhí)行save方法.");

//插入日志

logService.saveLog("用戶插入:"+user.getName());

returnresult;

LogService實現(xiàn)代碼如下:

@Transactional(propagation=Propagation.NESTED)

publicintsaveLog(Stringcontent){

//出現(xiàn)異常

inti=10/0;

returnlogMapper.saveLog(content);

最終執(zhí)行結果,用戶表和日志表都沒有添加任何數(shù)據(jù)。

執(zhí)行流程描述:

UserController中調(diào)用了UserService的添加用戶方法,UserService使用NESTED循環(huán)嵌套事務,并成功執(zhí)行了添加用戶的方法。UserService中調(diào)用了LogService的添加方法,LogService使用了NESTED循環(huán)嵌套事務,但在方法執(zhí)行中出現(xiàn)的異常,因此回滾了當前事務。因為UserService使用的是嵌套事務,所以發(fā)生回滾的事務是全局的,也就是說UserSer

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論