數據庫事務問題

什麼是數據庫事務

事務:一組邏輯操作單元,使數據從一種狀態轉換到另一種狀態
事務處理保證所有的事務都作爲一個工作單元執行,即使出現了故障,都不能改變這種執行方式,當在一個事務中執行多個操作時,要麼所有的事務都被提交,那麼這些操作就 永遠的保存下來,要麼數據庫系統放棄所做的所有修改,將整個事務回滾到最初的狀態
爲確保數據庫中數據的一致性,數據的操縱應該是離散的成組的邏輯單元,當它全部完成時,數據的一致性可以保持,而當這個單元中的一部分操作失敗,整個事務全部被歸爲錯誤操作,所有從最初開始的操作全部回退到最初的開始狀態

JDBC事務處理

1.數據庫一旦提交就不可以回滾
2.如何判斷數據庫已經提交
當一個連接對象被創建時,默認情況下是自動提交事務,每次執行一條sql語句時,如果執行成功,則向數據庫自動提交,而不能回滾
關閉數據庫連接,數據就會自動的提交,如果有多個操作,每個操作使用的是自己單獨的連接,則無法保證事務,即同一個事務的多個操作必須在同一個連接下

處理方法

調用Connection對象中的setAutoCommit(false),取消事務的自動提交,在所有sql語句執行完之後調用對象中的commit();提交事務在出現異常時在處理異常的方法調用rollBack();方法,使事務回滾但最初狀態

注意

如果Connection沒有被關閉,還可能會被重複使用,則需要恢復自動提交狀態調用setAutoCommit(true);在使用數據庫連接池技術是,執行close()方法前建議恢復自動提交狀態

@Test
public void testUpdate(){
    Connection conn = null;
    try {
        conn = JDBCUtils.getConnection();
        //取消數據的自動提交
        conn.setAutoCommit(false);
        String sql1 = "update user_table set balance = balance - 100 where user = ?";
        update(conn,sql1,"AA");
        //異常
        System.out.println(100 / 0);
        String sql2 = "update user_table set balance = balance + 100 where user = ?";
        update(conn,sql2,"BB");
        //提交數據
        conn.commit();
    } catch (Exception e){
        e.printStackTrace();
        //回滾數據
        try {
            conn.rollback();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }

    } finally {
        try {
            conn.setAutoCommit(true);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        JDBCUtils.closeResource(conn,null);
    }

}
//考慮數據庫事務
public void update(Connection conn,String sql,Object ...args)  {
    //獲取數據庫連接
    PreparedStatement ps = null;
    try {
        conn = JDBCUtils.getConnection();
        //預編譯sql語句返回PreparedStatement的實例
        ps = conn.prepareStatement(sql);
        //填充佔位符
        for(int i = 0; i < args.length; i++){
            ps.setObject(i+1,args[i] );
        }
        //執行
        ps.execute();
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        JDBCUtils.closeResource(null,ps);
    }
    //關閉資源
}

表數據在這裏插入圖片描述

事務的ACID屬性

1原子性(Atomicity)
原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。
2一致性(Consistency)
事務必須是數據庫從一個一致性狀態變換到另外一個一致性狀態
3隔離性(Isolation)
事務的隔離性是指一個事務的執行不能被其他事務干擾,即事務內部的操作和使用的數據庫不受其他影響
4持久性(Durability)
事務的持久性是指一個事務一旦被提交,則對數據庫中的數據的改變將是永久性的,接下來的其他操作和故障將不會對其有任何影響

數據操作過程中可能出現的問題(針對隔離性)

對於同時運行多個事務時,當這些事務訪問數據庫中相同的數據時,如果沒有采取必要的隔離機制,就會導致各種併發問題

髒讀:對於兩個事務t1和t2,t1讀取了以被t2更新但沒有提交的字段,在此之後如果t2回滾,t1讀取的內容就是臨時且無效的

不可重複讀:對於兩個事務t1和t2,t1讀取了一個字段,之後t2更新了該字段,之後t1再次讀取該字段,值也會改變

幻讀:對於兩個事務t1和t2,t1從一個表中讀取了一個字段,然後t2在該表中插入了一些新的行,之後t1在此讀取則會多出現幾行

數據庫的四種隔離級別:(一致性和併發性:一致性越好,併發性越差)

在這裏插入圖片描述
Oracle支持兩種事務隔離級別:READ COMMITED,SERIALIZABLE 默認爲第一種
Mysql支持4種隔離級別,默認的隔離級別爲:REPEATABLE READ

#查看當前的隔離級別
select @@tx_isolation;
設置mysql連接的隔離級別
set transaction isolation level read committed;
#設置數據庫系統的全局隔離級別
set global transaction isolation level read committed;
發佈了3 篇原創文章 · 獲贊 7 · 訪問量 2834
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章