溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何剖析Spring高級事務管理難點

發布時間:2021-10-29 18:06:18 來源:億速云 閱讀:184 作者:柒染 欄目:編程語言

今天就跟大家聊聊有關如何剖析Spring高級事務管理難點,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

1、Spring事務傳播行為

所謂事務傳播行為就是多個事務方法相互調用時,事務如何在這些方法間傳播。Spring支持7種事務傳播行為

PROPAGATION_REQUIRED(加入已有事務)

如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。這是最常見也是默認的方式。

PROPAGATION_SUPPORTS(跟隨環境)

支持當前事務,如果當前沒有事務,就以非事務方式執行。

PROPAGATION_MANDATORY(需要事務)

使用當前的事務,如果當前沒有事務,就拋出異常。

PROPAGATION_REQUIRES_NEW(獨立事務)

新建事務,如果當前存在事務,把當前事務掛起。

PROPAGATION_NOT_SUPPORTED(非事務方式)

以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

PROPAGATION_NEVER(排除事務)

以非事務方式執行,如果當前存在事務,則拋出異常。

PROPAGATION_NESTED(嵌套事務)

如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行與PROPAGATION_REQUIRED類似的操作。

Spring默認的事務傳播行為是PROPAGATION_REQUIRED,它適合于絕大多數的情況。假設ServiveX#methodX()都工作在事務環境下(即都被Spring事務增強了),假設程序中存在如下的調用鏈:Service1#method1()->Service2#method2()->Service3#method3(),那么這3個服務類的3個方法通過Spring的事務傳播機制都工作在同一個事務中。

如果在一個ServiceA和a()方法中啟動一個線程,在這個新創建的線程中執行ServiceB的事務方法b()。在相同線程中進行相互嵌套調用的事務方法工作于相同的事務中。如果這些相互嵌套調用的方法工作在不同的線程中,不同線程下的事務方法工作在獨立的事務中。

2、多種數據持久方法事務管理

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

如何剖析Spring高級事務管理難點

1)不同持久方式的事務統一

Spring提供了一個能從當前事務上下文中獲取綁定的數據連接的工具類,那就是DataSourceUtils。Spring強調必須使用DataSourceUtils工具類獲取數據連接。

 static Connection doGetConnection(DataSource dataSource)

首先嘗試從事務上下文中獲取連接,失敗后再從數據源獲取連接;

static Connection getConnection(DataSource dataSource)

doGetConnection方法的功能一樣,實際上,它內部就是調用doGetConnection方法獲取連接的;

static void  doReleaseConnection(Connection con, DataSource dataSource)

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

static void release Connection(Connection con, DataSource dataSource)

和doReleaseConnection方法的功能一樣,實際上,它內部就是調用doReleaseConnection方法獲取連接的;

測試demo:

@Service public class TestTranscationServiceImpl implements TestTranscationService {         @Autowired     private TestTranscationDao testTranscationDao;         @Override     @Transactional     public int test(){          testTranscationDao.update1();          testTranscationDao.update2();                 return 0;      }  }
@Autowired     private JdbcTemplate jdbcTemplate;         @Override     public int update1() {          //1.獲得數據庫連接          Connection con = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());          try {              con.prepareStatement("update grade_info set grade_name='11' where grade_id=1").executeUpdate();          } catch (SQLException e) {              throw new RuntimeException(e);          }finally {              //2如果當前方法沒有上下文事務管理,不釋放數據庫連接會造成數據庫連接泄露              //如果存在上下文事務,調用或者不調用數據庫連接釋放都沒有問題              DataSourceUtils.releaseConnection(con, jdbcTemplate.getDataSource());          }          return 0;         }         @Override     public int update2(){          //3.獲得數據庫連接   和1的數據庫連接是同一個連接          Connection con = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());          try {              //4.這種方法取到的數據庫連接和 1,3取到的數據庫連接不同              Connection conn = jdbcTemplate.getDataSource().getConnection();              conn.close();          } catch (SQLException e) {              e.printStackTrace();          }          return jdbcTemplate.update("update grade_info set grade_name='高中三年級' where grade_id=1");      }

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

如何剖析Spring高級事務管理難點

2)Hibernate和JDBC混合使用注意事項

由于Hibernate一級緩存的原因,在通過save,update,delete等方法操作數據時,并沒有真正向數據庫發送SQL,只有調用flush()時,Hibernate才會將一級緩存中的狀態變化同步到數據庫中。

Hibernate的事務管理在提交事務時,會自動調用flush()操作,將一級緩存同步到數據庫中,此時才會將產生并向數據庫發送SQL語句。

正是因為以上原因的存在,所有在混合使用JDBC和Hibernate時,可能存在丟失更新的問題。

如何剖析Spring高級事務管理難點

在混合使用Hibernate和JDBC時,JDBC的操作不會同步到Hibernate的緩存中(一級緩存及二級緩存),Hibernate緩存中的狀態變更也不被JDBC感知。因此混合使用時必須特別關注這一點。

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

3、Spring的事務增強限制條件

由于Spring事務管理是基于接口代理或動態字節碼技術,通過AOP實施事務增強的。

對于基于接口動態代理的AOP事務增強來說,由于接口的方法是public的,這就要求實現類的實現方法必須是public的(不能是protected,private等),同時不能使用static的修飾符。所以,可以實施接口動態代理的方法只能是使用“public”或“public final”修飾符的方法,其它方法不可能被動態代理,相應的也就不能實施AOP增強,也即不能進行Spring事務增強了。

基于CGLib字節碼動態代理的方案是通過擴展被增強類,動態創建子類的方式進行AOP增強植入的。由于使用final,static,private修飾符的方法都不能被子類覆蓋,相應的,這些方法將不能被實施的AOP增強。所以,必須特別注意這些修飾符的使用,以免不小心成為事務管理的漏網之魚。

4、Spring事務管理的異常捕捉,事務回滾

spring的事務管理器只對 unchecked exception進行異?;貪L,Error和RuntimeException及其子類是unchecked exception.其他exception是checked exception. 

如果在service層中,使用了try ,catch來捕捉異常,導致sevice層出現的異常被 “截留”,無法拋出給事務管理器,這就給事務管理器造成一種假象,就像程序在運行中,沒有產生任何問題,因此也就不會對出現 runtimeException進行回滾操作。

看完上述內容,你們對如何剖析Spring高級事務管理難點有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女