一般觀念認爲,事務與數據庫有關。事務是訪問數據庫的一個操做序列,數據庫應用系統經過事務集來完成對數據庫的存取。事務的正確執行使得數據庫從一種狀態轉換成另外一種狀態。java
事務必須服從ISO/IEC所制定的ACID原則。ACID是原子性(atomicity)、一致性(consistency)、隔離性(isolation)和持久性(durability)的縮寫事務必須服從ISO/IEC所制定的ACID原則。ACID是原子性(atomicity)、一致性(consistency)、隔離性(isolation)和持久性(durability)的縮寫。程序員
即不可分割性,事務要麼所有被執行,要麼就所有不被執行。若是事務的全部子事務所有提交成功,則全部的數據庫操做被提交,數據庫狀態發生轉換;若是有子事務失敗,則其餘子事務的數據庫操做被回滾,即數據庫回到事務執行前的狀態,不會發生狀態轉換。sql
事務的執行使得數據庫從一種正確狀態轉換成另外一種正確狀態。數據庫
在事務正確提交以前,不容許把該事務對數據的任何改變提供給任何其餘事務,即在事務正確提交以前,它可能的結果不該顯示給任何其餘事務。 服務器
事務正確提交後,其結果將永久保存在數據庫中,即便在事務提交後有了其餘故障,事務的處理結果也會獲得保存。 網絡
既然事務的概念從數據庫而來,那Java事務是什麼?之間有什麼聯繫?分佈式
實際上,一個Java應用系統,若是操做數據庫,經過JDBC來實現的。那麼增長、修改、刪除都是經過相應方法間接來實現的,事務的控制也相應轉移到Java程序代碼中。所以,數據庫操做的事務習慣上就稱爲Java事務。工具
簡單一句話:保持數據的一致性。學習
Java事務的類型有三種:JDBC事務、JTA(Java Transaction API)事務、容器事務。這裏都是最簡單的介紹,最後還會介紹下jdbc事務的使用,其餘兩種你們能夠本身搜下學習下。編碼
JDBC 事務是用 Connection 對象控制的。JDBC Connection 接口( java.sql.Connection )提供了兩種事務模式:自動提交和手工提交。 java.sql.Connection 提供瞭如下控制事務的方法:
public void setAutoCommit(boolean) public boolean getAutoCommit() public void commit() public void rollback()
使用 JDBC 事務界定時,您能夠將多個 SQL 語句結合到一個事務中。JDBC 事務的一個缺點是事務的範圍侷限於一個數據庫鏈接。一個 JDBC 事務不能跨越多個數據庫。
JTA是一種高層的,與實現無關的,與協議無關的API,應用程序和應用服務器可使用JTA來訪問事務。JTA容許應用程序執行分佈式事務處理--在兩個或多個網絡計算機資源上訪問而且更新數據,這些數據能夠分佈在多個數據庫上。JDBC驅動程序的JTA支持極大地加強了數據訪問能力。
若是計劃用 JTA 界定事務,那麼就須要有一個實現 javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC 驅動程序。一個實現了這些接口的驅動程序將能夠參與 JTA 事務。一個 XADataSource 對象就是一個 XAConnection 對象的工廠。 XAConnections 是參與 JTA 事務的 JDBC 鏈接,您將須要用應用服務器的管理工具設置 XADataSource 。J2EE 應用程序用 JNDI 查詢數據源。一旦應用程序找到了數據源對象,它就調用 javax.sql.DataSource.getConnection() 以得到到數據庫的鏈接。
XA 鏈接與非 XA 鏈接不一樣。必定要記住 XA 鏈接參與了 JTA 事務。這意味着 XA 鏈接不支持 JDBC 的自動提交功能。同時,應用程序必定不要對 XA 鏈接調用 java.sql.Connection.commit() 或者 java.sql.Connection.rollback() 。相反,應用程序應該使用 UserTransaction.begin()、 UserTransaction.commit() 和 serTransaction.rollback() 。
容器事務主要是J2EE應用服務器提供的,容器事務大可能是基於JTA完成,這是一個基於JNDI的,至關複雜的API實現。相對編碼實現JTA事務管理,咱們能夠經過EJB容器提供的容器事務管理機制(CMT)完成同一個功能,這項功能由J2EE應用服務器提供。這使得咱們能夠簡單的指定將哪一個方法加入事務,一旦指定,容器將負責事務管理任務。這是咱們土建的解決方式,由於經過這種方式咱們能夠將事務代碼排除在邏輯編碼以外,同時將全部困難交給J2EE容器去解決。使用EJB CMT的另一個好處就是程序員無需關心JTA API的編碼,不過,理論上咱們必須使用EJB。
首先,設置事務的提交方式爲非自動提交:conn.setAutoCommit(false);接下來,將須要添加事務的代碼放入try,catch塊中。而後,在try塊內添加事務的提交操做,表示操做無異常,提交事務:conn.commit();尤爲不要忘記,在catch塊內添加回滾事務,表示操做出現異常,撤銷事務:conn.rollback();最後,設置事務提交方式爲自動提交:conn.setAutoCommit(true);這樣,經過簡單的幾步,咱們就能夠完成對事務處理的編寫了。
con = DriverManager.getConnection(url, user, password); String result = ""; String sql1 = ""; // LAST_INSERT_ID() 獲取剛剛插入的自動遞增的ID String sql2 = ""; int flag; try { con.setAutoCommit(false);// 更改JDBC事務的默認提交方式 pstmt = con.prepareStatement(sql1); flag = pstmt.executeUpdate(); if (flag > 0) { pstmt = con.prepareStatement(sql2); int i = pstmt.executeUpdate(); if (i > 0) { con.commit();//提交JDBC事務 result = "add data success!!"; } else { result = "add data fail!!"; } } else { result = "add data fail!!"; } } catch (SQLException e) { try { con.rollback();//回滾JDBC事務 } catch (SQLException e1) { // TODO Auto-generated catch block result = "add data fail!! SQLException"; e1.printStackTrace(); } result = "add data fail!! SQLException"; e.printStackTrace(); } finally { try { con.setAutoCommit(true); // 恢復JDBC事務的默認提交方式 } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return result;
一、JDBC事務控制的侷限性在一個數據庫鏈接內,可是其使用簡單。
二、JTA事務的功能強大,事務能夠跨越多個數據庫或多個DAO,使用也比較複雜。
三、容器事務,主要指的是J2EE應用服務器提供的事務管理,侷限於EJB應用使用。
事務控制是構建J2EE應用不可缺乏的一部分,合理選擇應用何種事務對整個應用系統來講相當重要。通常說來,在單個JDBC 鏈接鏈接的狀況下能夠選擇JDBC事務,在跨多個鏈接或者數據庫狀況下,須要選擇使用JTA事務,若是用到了EJB,則能夠考慮使用EJB容器事務。