天天看點

spring學習筆記(21)程式設計式事務配置,service層概念引入通路資料庫事務導入多資料庫操作事務配置——引入Service層程式設計式事務模闆類:TransactionTemplate執行個體示範

通過直接開啟session而後儲存對象、查詢資料等操作,是沒有事務的。而如果我們的項目規模變大,業務邏輯日益複雜,我們在一個方法中進行大量的資料庫操作,而沒有事務管理的話,一旦中間哪一個操作環節出錯,後果是嚴重的。比如,一個使用者通過支付寶轉100塊到銀行賬戶,于是使用者的100塊先轉到了銀行,但這時資料庫異常中斷,銀行無法把100塊轉給使用者賬戶,這時事務又沒有復原,那麼可能使用者的100塊就白白損失掉了。

在spring中,有多種方式可以進行我們的事務配置,比如我們可以直接修改上面的方法,加上事務:

這樣,我們就能為我們的add方法加上簡單的事務了。

但這樣的話我們針對的隻是dao層add這個方法,但在實際中,我們可能需要同時控制大量dao的方法在同一個事務中,為此,我們可以建立service層來統一進行我們的業務邏輯處理。比如我們根據需求,需要先擷取使用者id,并修改使用者名稱,這裡設計兩個資料庫操作,但我們在同一個service類方法中完成。

在下例中,我們依然使用程式設計式事務,spring為此專門提供了模闆類transactiontemplate來滿足我們的需求。transactiontemplate是線程安全的,也即是說,我們可以在多個業務類中共享同一個transactiontemplate執行個體進行事務管理。

transactiontemplate有很多常用的屬性如:

1. isolationlevel:設定事務隔離級别

2. propagationbehavior:設定我們的事務傳播行為

3. readonly:設定為隻讀事務,即資料寫操作會失敗

4. timeout:設定連結過期時間,-1和預設為無逾時限制

5. transactionmanager:它是我們的ioc容器配置時的必要屬性,設定我們的事務管理對象。在本例中用到hibernate,為hibernatetransactionmanager。

transactiontemplate類在調用時主要用到的方法為execute(transactioncallback

action)。

其中transactioncallback為我們的回調接口,它隻有一個方法:

t dointransaction(transactionstatus status),這個方法内是有事務的。通常我們的資料庫查詢操作就在這個方法裡完成。

dointransaction方法的唯一入參是transactionstatus,它常用于檢視我們目前的事務狀态,它有兩個常用的方法:

1. createsavepoint():建立一個記錄點。

2. rollbacktosavepoint(savepoint):将事務復原到特定記錄點,這樣從復原處到記錄點範圍内所有的資料庫操作都會失效。

另外,dointransaction是有傳回值的,如果我們不需要傳回值,我們可以使用transactioncallback接口的一個子類transactioncallbackwithoutresult,它對應的抽象方法dointransactionwithoutresult(transactionstatus status)是沒有傳回值的。

下面開始我們的執行個體示範

對應的dao層類和部分方法如下所示:

如果對于hibernate不太了解,可以先不管我們的方法實作原理,隻需要知道對應的方法實作了什麼功能即可。在這裡。接下來我們要配置我們的spring容器,主要完成bean之間的依賴配置:

關于資料源和sessionfactory的配置執行個體如下:

配置完成後,就可以進行我們的測試了。在這裡,我用到了junit測試元件

調用測試方法,我們會看到控制台輸出如下相關資訊:

debug: org.hibernate.engine.jdbc.internal.logicalconnectionimpl - obtaining jdbc connection debug: org.hibernate.engine.jdbc.internal.logicalconnectionimpl - obtained jdbc connection debug: org.hibernate.engine.transaction.spi.abstracttransactionimpl - begin————————這裡我們的事務開始了 debug: org.hibernate.loader.loader - loading entity: [com.yc.model.user#1]——————————讀取id為1的使用者 debug: org.hibernate.loader.loader - done entity load//完成裝載工作 user [id=1, name=zenghao]——————獲得了我們的user資訊 user [id=1, name=newname]——————完成了修改操作 debug: org.springframework.orm.hibernate4.hibernatetransactionmanager - initiating transaction commit//初始化資料庫送出 debug: org.hibernate.engine.transaction.spi.abstracttransactionimpl - committing————————這時候才完成了事務送出 觀察列印資訊,我們會發現我們像資料庫發出了兩次請求(分别為擷取和更新)但事務才送出了一次。說明這兩個請求在同一個事務中。這樣我們就能確定多個資料庫操作在同一個事務内完成,一旦中間出現異常,能立即復原,取消前面的資料庫操作。 很多人都知道我們的mvc模式将後端業務分成了三層(dao,service,controller),從這裡,我們也能略微看出dao層和service層的功能職責了。dao主要完成資料庫查詢的封裝,而service層則調用dao層的資料庫查詢方法來完成我們的業務邏輯處理