日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
Spring高級(jí)事務(wù)管理難點(diǎn)剖析

1、Spring事務(wù)傳播行為

所謂事務(wù)傳播行為就是多個(gè)事務(wù)方法相互調(diào)用時(shí),事務(wù)如何在這些方法間傳播。Spring支持7種事務(wù)傳播行為

PROPAGATION_REQUIRED(加入已有事務(wù))

如果當(dāng)前沒(méi)有事務(wù),就新建一個(gè)事務(wù),如果已經(jīng)存在一個(gè)事務(wù)中,加入到這個(gè)事務(wù)中。這是最常見(jiàn)也是默認(rèn)的方式。

PROPAGATION_SUPPORTS(跟隨環(huán)境)

支持當(dāng)前事務(wù),如果當(dāng)前沒(méi)有事務(wù),就以非事務(wù)方式執(zhí)行。

PROPAGATION_MANDATORY(需要事務(wù))

使用當(dāng)前的事務(wù),如果當(dāng)前沒(méi)有事務(wù),就拋出異常。

PROPAGATION_REQUIRES_NEW(獨(dú)立事務(wù))

新建事務(wù),如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起。

PROPAGATION_NOT_SUPPORTED(非事務(wù)方式)

以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。

PROPAGATION_NEVER(排除事務(wù))

以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則拋出異常。

PROPAGATION_NESTED(嵌套事務(wù))

如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒(méi)有事務(wù),則執(zhí)行與PROPAGATION_REQUIRED類(lèi)似的操作。

Spring默認(rèn)的事務(wù)傳播行為是PROPAGATION_REQUIRED,它適合于絕大多數(shù)的情況。假設(shè)ServiveX#methodX()都工作在事務(wù)環(huán)境下(即都被Spring事務(wù)增強(qiáng)了),假設(shè)程序中存在如下的調(diào)用鏈:Service1#method1()->Service2#method2()->Service3#method3(),那么這3個(gè)服務(wù)類(lèi)的3個(gè)方法通過(guò)Spring的事務(wù)傳播機(jī)制都工作在同一個(gè)事務(wù)中。

如果在一個(gè)ServiceA和a()方法中啟動(dòng)一個(gè)線程,在這個(gè)新創(chuàng)建的線程中執(zhí)行ServiceB的事務(wù)方法b()。在相同線程中進(jìn)行相互嵌套調(diào)用的事務(wù)方法工作于相同的事務(wù)中。如果這些相互嵌套調(diào)用的方法工作在不同的線程中,不同線程下的事務(wù)方法工作在獨(dú)立的事務(wù)中。

2、多種數(shù)據(jù)持久方法事務(wù)管理

如果你采用了一個(gè)高端ORM技術(shù)(Hibernate,JPA,JDO),同時(shí)采用一個(gè)JDBC技術(shù)(Spring JDBC,iBatis),由于前者的會(huì)話(Session)是對(duì)后者連接(Connection)的封裝,Spring會(huì)“足夠智能地”在同一個(gè)事務(wù)線程讓前者的會(huì)話封裝后者的連接。所以,我們只要直接采用前者的事務(wù)管理器就可以了。下表給出了混合數(shù)據(jù)訪問(wèn)技術(shù)所對(duì)應(yīng)的事務(wù)管理器: 

1)不同持久方式的事務(wù)統(tǒng)一

Spring提供了一個(gè)能從當(dāng)前事務(wù)上下文中獲取綁定的數(shù)據(jù)連接的工具類(lèi),那就是DataSourceUtils。Spring強(qiáng)調(diào)必須使用DataSourceUtils工具類(lèi)獲取數(shù)據(jù)連接。

 static Connection doGetConnection(DataSource dataSource)

首先嘗試從事務(wù)上下文中獲取連接,失敗后再?gòu)臄?shù)據(jù)源獲取連接;

static Connection getConnection(DataSource dataSource)

doGetConnection方法的功能一樣,實(shí)際上,它內(nèi)部就是調(diào)用doGetConnection方法獲取連接的;

static void  doReleaseConnection(Connection con, DataSource dataSource)

釋放連接,放回到連接池中;

static void release Connection(Connection con, DataSource dataSource)

和doReleaseConnection方法的功能一樣,實(shí)際上,它內(nèi)部就是調(diào)用doReleaseConnection方法獲取連接的;

測(cè)試demo:

 
 
  1. @Service 
  2. public class TestTranscationServiceImpl implements TestTranscationService {  
  3.    
  4.     @Autowired 
  5.     private TestTranscationDao testTranscationDao;  
  6.    
  7.     @Override 
  8.     @Transactional 
  9.     public int test(){  
  10.         testTranscationDao.update1();  
  11.         testTranscationDao.update2();         
  12.         return 0;  
  13.     }  
 
 
  1. @Autowired 
  2.     private JdbcTemplate jdbcTemplate;  
  3.    
  4.     @Override 
  5.     public int update1() {  
  6.         //1.獲得數(shù)據(jù)庫(kù)連接  
  7.         Connection con = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());  
  8.         try {  
  9.             con.prepareStatement("update grade_info set grade_name='11' where grade_id=1").executeUpdate();  
  10.         } catch (SQLException e) {  
  11.             throw new RuntimeException(e);  
  12.         }finally {  
  13.             //2如果當(dāng)前方法沒(méi)有上下文事務(wù)管理,不釋放數(shù)據(jù)庫(kù)連接會(huì)造成數(shù)據(jù)庫(kù)連接泄露  
  14.             //如果存在上下文事務(wù),調(diào)用或者不調(diào)用數(shù)據(jù)庫(kù)連接釋放都沒(méi)有問(wèn)題  
  15.             DataSourceUtils.releaseConnection(con, jdbcTemplate.getDataSource());  
  16.         }  
  17.         return 0;  
  18.    
  19.     }  
  20.    
  21.     @Override 
  22.     public int update2(){  
  23.         //3.獲得數(shù)據(jù)庫(kù)連接   和1的數(shù)據(jù)庫(kù)連接是同一個(gè)連接  
  24.         Connection con = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());  
  25.         try {  
  26.             //4.這種方法取到的數(shù)據(jù)庫(kù)連接和 1,3取到的數(shù)據(jù)庫(kù)連接不同  
  27.             Connection conn = jdbcTemplate.getDataSource().getConnection();  
  28.             conn.close();  
  29.         } catch (SQLException e) {  
  30.             e.printStackTrace();  
  31.         }  
  32.         return jdbcTemplate.update("update grade_info set grade_name='高中三年級(jí)' where grade_id=1");  
  33.     } 

Spring為每個(gè)數(shù)據(jù)訪問(wèn)技術(shù)框架都提供了一個(gè)獲取事務(wù)上下文綁定的數(shù)據(jù)連接(或其衍生品)的工具類(lèi)和數(shù)據(jù)源(或其衍生品)的代理類(lèi)。 

2)Hibernate和JDBC混合使用注意事項(xiàng)

由于Hibernate一級(jí)緩存的原因,在通過(guò)save,update,delete等方法操作數(shù)據(jù)時(shí),并沒(méi)有真正向數(shù)據(jù)庫(kù)發(fā)送SQL,只有調(diào)用flush()時(shí),Hibernate才會(huì)將一級(jí)緩存中的狀態(tài)變化同步到數(shù)據(jù)庫(kù)中。

Hibernate的事務(wù)管理在提交事務(wù)時(shí),會(huì)自動(dòng)調(diào)用flush()操作,將一級(jí)緩存同步到數(shù)據(jù)庫(kù)中,此時(shí)才會(huì)將產(chǎn)生并向數(shù)據(jù)庫(kù)發(fā)送SQL語(yǔ)句。

正是因?yàn)橐陨显虻拇嬖冢性诨旌鲜褂肑DBC和Hibernate時(shí),可能存在丟失更新的問(wèn)題。

在混合使用Hibernate和JDBC時(shí),JDBC的操作不會(huì)同步到Hibernate的緩存中(一級(jí)緩存及二級(jí)緩存),Hibernate緩存中的狀態(tài)變更也不被JDBC感知。因此混合使用時(shí)必須特別關(guān)注這一點(diǎn)。

由于混合數(shù)據(jù)訪問(wèn)技術(shù)的方案的事務(wù)同步而緩存不同步的情況,所以***用Hibernate完成讀寫(xiě)操作,而用Spring JDBC完成讀的操作。如用Spring JDBC進(jìn)行簡(jiǎn)要列表的查詢,而用Hibernate對(duì)查詢出的數(shù)據(jù)進(jìn)行維護(hù)。如果確實(shí)要同時(shí)使用Hibernate和Spring JDBC讀寫(xiě)數(shù)據(jù),則必須充分考慮到Hibernate緩存機(jī)制引發(fā)的問(wèn)題:必須充分分析數(shù)據(jù)維護(hù)邏輯,根據(jù)需要,及時(shí)調(diào)用Hibernate的flush()方法,以免覆蓋Spring JDBC的更改,在Spring JDBC更改數(shù)據(jù)庫(kù)時(shí),維護(hù)Hibernate的緩存。

3、Spring的事務(wù)增強(qiáng)限制條件

由于Spring事務(wù)管理是基于接口代理或動(dòng)態(tài)字節(jié)碼技術(shù),通過(guò)AOP實(shí)施事務(wù)增強(qiáng)的。

對(duì)于基于接口動(dòng)態(tài)代理的AOP事務(wù)增強(qiáng)來(lái)說(shuō),由于接口的方法是public的,這就要求實(shí)現(xiàn)類(lèi)的實(shí)現(xiàn)方法必須是public的(不能是protected,private等),同時(shí)不能使用static的修飾符。所以,可以實(shí)施接口動(dòng)態(tài)代理的方法只能是使用“public”或“public final”修飾符的方法,其它方法不可能被動(dòng)態(tài)代理,相應(yīng)的也就不能實(shí)施AOP增強(qiáng),也即不能進(jìn)行Spring事務(wù)增強(qiáng)了。

基于CGLib字節(jié)碼動(dòng)態(tài)代理的方案是通過(guò)擴(kuò)展被增強(qiáng)類(lèi),動(dòng)態(tài)創(chuàng)建子類(lèi)的方式進(jìn)行AOP增強(qiáng)植入的。由于使用final,static,private修飾符的方法都不能被子類(lèi)覆蓋,相應(yīng)的,這些方法將不能被實(shí)施的AOP增強(qiáng)。所以,必須特別注意這些修飾符的使用,以免不小心成為事務(wù)管理的漏網(wǎng)之魚(yú)。

4、Spring事務(wù)管理的異常捕捉,事務(wù)回滾

spring的事務(wù)管理器只對(duì) unchecked exception進(jìn)行異?;貪L,Error和RuntimeException及其子類(lèi)是unchecked exception.其他exception是checked exception.  

如果在service層中,使用了try ,catch來(lái)捕捉異常,導(dǎo)致sevice層出現(xiàn)的異常被 “截留”,無(wú)法拋出給事務(wù)管理器,這就給事務(wù)管理器造成一種假象,就像程序在運(yùn)行中,沒(méi)有產(chǎn)生任何問(wèn)題,因此也就不會(huì)對(duì)出現(xiàn) runtimeException進(jìn)行回滾操作。


本文名稱(chēng):Spring高級(jí)事務(wù)管理難點(diǎn)剖析
網(wǎng)頁(yè)URL:http://www.dlmjj.cn/article/dhsgioo.html