清單 1. 資金轉移的樣本 SQL 代碼 SELECT accountBalance INTO aBalance FROM Accounts WHERE accountId=aId; IF (aBalance >= transferAmount) THEN UPDATE Accounts SET accountBalance = accountBalance - transferAmount WHERE accountId = aId; UPDATE Accounts SET accountBalance = accountBalance + transferAmount WHERE accountId = bId; INSERT INTO AccountJournal (accountId, amount) VALUES (aId, -transferAmount); INSERT INTO AccountJournal (accountId, amount) VALUES (bId, transferAmount); ELSE FAIL "Insufficient funds in account"; END IF
假如我們把這個操作作為五個單獨的事務來執行會發生什么情況?這樣不僅會使執行速度變慢(由于事務開銷),還會失去一致性。例如,假如一個人從帳戶 A 取了錢,作為執行第一次 SELECT(檢查余額)和隨后的記入借方 UPDATE 之間的一個單獨事務的一部分,會發生什么情況?這樣會違反我們認為這段代碼會強制遵守的業務規則 ? 帳戶余額應該是非負的。假如在第一次 UPDATE 和第二次 UPDATE 之間系統失敗會發生什么情況?現在,當系統恢復時,錢已經離開了帳戶 A 但還沒有記入帳戶 B 的貸方,并且也無記錄說明原因。這樣,哪個帳戶的所有者都不會開心。
事務模式 Bean 類型 在事務 T 內被調用時的行為 在事務外被調用時的行為 Required 會話、實體、消息驅動 在 T 中征用 新建事務 RequiresNew 會話、實體 新建事務 新建事務 Supports 會話、消息驅動 在 T 中征用 不帶事務運行 Mandatory 會話、實體 在 T 中征用 出錯 NotSupported 會話、消息驅動 不帶事務運行 不帶事務運行 Never 會話、消息驅動 出錯 不帶事務運行
在只使用容器治理的事務的應用程序中,只有組件調用事務模式為 Required 或 RequiresNew 的 EJB 方法時才啟動事務。假如容器創建一個事務作為調用事務性方法的結果,當該方法完成時將關閉該事務。假如方法正常返回,容器將提交事務(除非應用程序已經要求回滾事務)。假如方法通過拋出一個異常退出,容器將回滾事務并傳播該異常。假如在現有事務 T 中調用了一個方法,并且事務模式指定應該不帶事務運行該方法或者在新事務中運行該方法,那么事務 T 將被暫掛,一直到方法完成,然后先前的事務 T 被恢復。
對于大多數數據庫,缺省的隔離級別為“讀已提交的”,這是個很好的缺省選擇,因為它阻止事務在事務中的任何給定的點看到應用程序數據的不一致視圖。“讀已提交的”是一個很不錯的隔離級別,用于大多數典型的短事務,比如獲取報表數據或獲取要顯示給用戶的數據的時候(多半是作為 Web 請求的結果),也用于將新數據插入到數據庫的情況。
Jim Grey 和 Andreas Reuter 合著的 Transaction Processing: Concepts and Techniques 是關于事務處理這個主題的權威著作。
Philip Bernstein 和 Eric Newcomer 合著的 Principles of Transaction Processing 是關于這個主題的很好的介紹;它包含了許多歷史和概念。
Ed Roman、Tyler Jewell 和 Scott Ambler 合著的 Mastering Enterprise JavaBeans 是關于 J2EE 和 EJB 技術的很好的介紹。
通過 Transaction Management under J2EE 1.2(JavaWorld,2000 年 7 月)學習聲明式事務劃分的基礎知識。
來自 WebSphere 開發者園地的這篇技術記要量化減少隔離級別的好處。
白皮書“WebSphere application Server Development Best Practices for Performance and Scalability”描述了用來治理 J2EE 應用程序性能和可伸縮性的幾種很有用的技術。
Visual Age 開發者園地上發表了一篇文章,這篇文章檢查了 J2EE 應用程序中的數據庫訪問和并發治理問題。
PreciseJava 中的教程“Best practices to improve performance in JDBC”描述了幾種有用的數據庫應用程序性能最優化。
請在 developerWorks Java 技術專區中查找其它關于 Java 技術的內容。
關于作者 Brian Goetz 是一位軟件顧問,在過去 15 年間一直從事專業軟件開發。他是 Quiotix,一家位于加利福尼亞,洛斯拉圖斯(Los Altos)的軟件開發和咨詢公司的總顧問。請參閱流行的業界出版物中 Brian 已經發表和即將發表的文章。您可以通過 brian@quiotix.com 與 Brian 聯系。