Java 事務及隔離級別

Java事務


1)       說到事務,不得不提的就是ACID特性,再次回顧: java

  Ø  原子性(atomicity):組成事務處理的語句造成了一個邏輯單元,不能只執行其中的一部分。 sql

  Ø  一致性(consistency):在事務處理執行先後,數據庫是一致的(數據庫數據完整性約束)。 數據庫

  Ø  隔離性(isolcation):一個事務處理對另外一個事務處理的影響。 多線程

  Ø  持續性(durability):事務處理的效果可以被永久保存下來 。 併發

2)       而後就是事務在Java中的最基本操做: 分佈式

  Ø  connection.setAutoCommit(false);//打開事務。 學習

  Ø  connection.commit();//提交事務。 測試

  Ø  connection.rollback();//回滾事務。 atom

  這裏須要提的就是,當只想撤銷事務中的部分操做時可以使用SavePoint spa

  Ø  SavePoint sp = connection.setSavepoint();

  Ø  connection.rollerbak(sp);connection.commit();

3)       下面用一個實例代碼來展現一下:

[java]   view plain copy 在CODE上查看代碼片 派生到個人代碼片
  1. package cn.itcast.jdbc;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.ResultSet;  
  5. import java.sql.SQLException;  
  6. import java.sql.Savepoint;  
  7. import java.sql.Statement;  
  8. /** 
  9.  * 事務測試 
  10.  */  
  11. public class SavePointTest {  
  12.   
  13.     public static void main(String[] args) throws SQLException {  
  14.         testTransaction();  
  15.     }  
  16.   
  17.     static void testTransaction() throws SQLException {  
  18.         Connection conn = null;  
  19.         Statement st = null;  
  20.         ResultSet rs = null;  
  21.         Savepoint sp = null;  
  22.         try {  
  23.             //獲取Connection(JdbcUtils爲自定義的包裝類,這裏不作解釋)  
  24.             conn = JdbcUtils.getConnection();  
  25.             //開啓事務  
  26.             conn.setAutoCommit(false);            
  27.             st = conn.createStatement();  
  28.             //id爲1的人的Money減10  
  29.             String sql = "update user set money=money-10 where id=1";  
  30.             st.executeUpdate(sql);  
  31.             //********************回滾界限***************************  
  32.             //設置回滾點(savepoint)  
  33.             sp = conn.setSavepoint();  
  34.             //********************回滾界限***************************  
  35.             //id爲2的人的Money減10  
  36.             sql = "update user set money=money-10 where id=3";  
  37.             st.executeUpdate(sql);        
  38.             sql = "select money from user where id=2";  
  39.             rs = st.executeQuery(sql);  
  40.             float money = 0.0f;  
  41.             if (rs.next()) {  
  42.                 money = rs.getFloat("money");  
  43.             }  
  44.             if (money > 300){  
  45.                 throw new RuntimeException("已經超過最大值!");  
  46.             }  
  47.             //id爲2的人的Money加10  
  48.             sql = "update user set money=money+10 where id=2";  
  49.             st.executeUpdate(sql);  
  50.             //提交事務  
  51.             conn.commit();  
  52.         } catch (RuntimeException e) {  
  53.             if (conn != null && sp != null) {  
  54.                 //回滾事務,注意裏面的參數sp即爲咱們上面設置的savePoint,若是回滾的話只能回滾到savePoint如下的部分  
  55.                 //上面的部分不會獲得回滾  
  56.                 conn.rollback(sp);  
  57.                 conn.commit();  
  58.             }  
  59.             throw e;  
  60.         } catch (SQLException e) {  
  61.             if (conn != null)  
  62.                 conn.rollback();  
  63.             throw e;  
  64.         } finally {  
  65.             //釋放資源(JdbcUtils爲自定義類)  
  66.             JdbcUtils.free(rs, st, conn);  
  67.         }  
  68.     }  
  69. }  

  上面全部的操做(CRUD)都是在同一個數據源上的操做,沒法處理跨多數據源(分佈式)操做。跨多個數據源的事務就要使用JTA容器實現事務。根本思想就是「分紅兩階段提交」,具體內容這裏不作介紹。

[java]   view plain copy 在CODE上查看代碼片 派生到個人代碼片
  1. javax.transaction.UserTransaction tx = (UserTransaction)ctx.lookup(「jndiName");  
  2.     tx.begin();  
  3.     //connection1 connection2 (可能來自不一樣的數據庫)…   
  4.     tx.commit();//tx.rollback();  

隔離級別


1)      爲了應對多線程併發讀取數據時出現的問題,事務有了「隔離級別」特性,多線程併發讀取數據通常會引起以下三個問題

  Ø  髒讀(dirtyreads)

  Ø  不可重複讀(non-repeatablereads)

  Ø  幻讀(phantomread)

下面進行簡要介紹:

  Ø  髒讀:一個事務讀取了另外一個未提交的並行事務寫的數據。

  Ø  不可重複讀:一個事務從新讀取前面讀取過的數據, 發現該數據已經被另外一個已提交的事務修改過。

  Ø  幻讀:一個事務從新執行一個查詢,返回一套符合查詢條件的行, 發現這些行由於其餘最近提交的事務而發生了改變。

2)       爲了處理上面的讀數據問題,java事務提供了4種隔離級別,以下:

  Ø  讀未提交(Read uncommitted)

  Ø  讀已提交(Readcommitted)

  Ø  可重複讀(Repeatableread)

  Ø  可串行化(Serializable)

3)       4種隔離級別與上面3個問題的對應關係以下:


  

  注意上面的「可能」二字。


4)       隔離級別的設定:

  connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

  在代碼中的應用:

  


總結


  除了隔離級別,上面全部的東西在.net中相信你們都很熟悉。固然在八期的.net教務系統也用到了事務隔離級別這一點,當時本身仍是初步接觸,如今能夠詳細的學習,能夠看到學習就是一個不斷反覆的過程。

http://blog.csdn.net/wang379275614/article/details/24818397

相關文章
相關標籤/搜索