關系數據庫等資源管理器提供了一個事務管理器和一個用于控制事務的API。 熟悉JDBC的人會知道,由于設置autocommit = true,默認情況下將啟動事務。 每個更改數據庫的語句都會自動提交。 可以通過將autocommit設置為false來更改此行為。 現在,程序員必須顯式開始事務,然后提交或回滾該事務。
僅處理一種資源(例如一個數據庫)的事務稱為本地事務。 跨多個資源(例如多個數據庫或一個數據庫和一個消息傳遞引擎)的事務稱為全局事務。 全局事務是使用XA協議實現的,該協議涉及兩階段提交。 JTA規范描述了Java API,供程序員使用全局事務。 JDBC中的事務方法(例如begin,commit,rollback)僅適用于JDBC和關系數據庫,而JTA可以與任何事務資源一起使用。
但是,涉及事務處理的代碼是可以由框架處理的樣板代碼。 在方法開始時,您需要開始一個事務,并且在方法完成時,您需要提交或回滾該事務。 如果您使用過EJB,可能會很熟悉,您可以在部署描述符中指定方法應在其中執行的事務環境。 例如,您可能會說RequiresNew,這意味著在調用該方法之前啟動一個新事務。 容器在調用方法之前啟動新事務,并在方法返回時提交新事務。 程序員不需要編寫任何Java代碼來處理事務。
在本文的其余部分,我們將通過一個示例討論使用Spring進行聲明式事務管理。
對于本教程,您將需要:
(1) Spring3.0
(2) Eclipse是可選的。 我使用eclipse作為我的IDE。 Eclipse使您可以導出可以部署到Tomcat的戰爭。 但是您也可以使用其他IDE或命令行工具。 (3)您可以從springjdbcwithTransaction.zip下載此示例的源代碼。
我們重新使用了JDBC和Spring博客中的示例,該博客是我們之前寫的。 讓我們為MemberSpringJDBCDAO添加事務支持。 此類具有insertMember方法,該方法將成員插入數據庫。 讓我們稍微修改一下方法,以在插入數據庫后拋出RuntimeException。 添加了運行時異常,以假裝在更新數據庫時業務邏輯中發生了錯誤。
public int insertMember(Member member) {JdbcTemplate jt = getJdbcTemplate() ;Object[] params = new Object[{member.getFirstname(),member.getLastname(),member.getStreet(),member.getCity(),member.getZip(),member.getEmail(),member.getPassword()} ;int ret = jt.update(insert_sql, params) ;throw new RuntimeException("simulate Error condition') ;return ret ;
}
在這種方法中,您是否希望將插入內容提交給數據庫? 答案是肯定的,盡管這不是理想的行為。 JDBC的默認行為是autocommit = true,這意味著每個插入或更新都將立即提交。 您可以設置autocommit = false,并在方法末尾顯式提交或回滾。 但是讓您的容器處理此問題要容易得多。
要將聲明式事務管理添加到上述方法中,請使用以下步驟:
步驟1:在springjdbcdao.xml中定義一個事務管理器
<bean id="txManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"/>
Spring與事務管理器一起開始和完成事務。
步驟2:啟用對交易注釋的支持
添加到springjdbcdao.xml
<tx:annotation-driven transaction-manager="txManager"/>
步驟3:將@Transactional批注添加到insertMember方法
@Transactional
public int insertMember(Member member) {
...
@Transactional可以接受屬性,但我們將使用以下默認值:
傳播方式:必填
必需表示需要進行交易。 如果沒有事務,Spring將請求事務管理器啟動一個事務。 其他可能的值是Requires_New,它告訴事務管理器始終掛起現有事務并開始一個新事務。
隔離級別:默認
使用基礎資源管理器的默認隔離級別。
回滾:任何運行時異常都會觸發回滾
步驟4:使用Junit測試MemberSpringJDBCDAOTest運行更新的insertMember方法。
您將從事務管理器中看到以下日志,指示該事務已回滾。
org.springframework.jdbc.datasource.DataSourceTransactionManager –啟動事務回滾
2501 [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager –啟動事務回滾
2501 [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager –在Connection [org.apache.derby.impl.jdbc.EmbedConnection40@13320911(XID = 2827),(SESSIONID = 1),(DATABASE = c:\ manoj \ mjprojects \ database \ pumausers)(DRDAID = null)2501 [main]調試org.springframework.jdbc.datasource.DataSourceTransactionManager –在Connection [org.apache.derby.impl.jdbc]上回滾JDBC事務。 EmbedConnection40 @ 13320911(XID = 2827),(SESSIONID = 1),(數據庫= c:\ manoj \ mjprojects \ database \ pumausers),(DRDAID = null)] 2511
使用SQL檢查數據庫表。 確認未添加任何記錄。
步驟5:從insertMember方法中刪除runtimeexception,然后再次運行測試。
Spring調試日志顯示了事務已提交。 使用SQL檢查數據庫表。 確認記錄已添加到表中。
總之,事務對于維護數據源的ACID屬性是必需的。 使用Spring的聲明式事務使該任務更加容易。
參考: The Khangaonkar報告中來自我們的JCG合作伙伴 Manoj的Spring和聲明性交易 。
相關文章 :
- YouTube Java API入門
- Google Guava庫必需品
- Java Code Geeks Andygene Web原型
- 使用Spring Security保護GWT應用程序
翻譯自: https://www.javacodegeeks.com/2011/09/spring-declarative-transactions-example.html