1. 程式人生 > >資料庫關於事務的一些筆記

資料庫關於事務的一些筆記

事務

事務的概念:事務是指邏輯上的一系列操作, 組成這個操作的所有單元,要不一起成功,要不就是一起失敗。

  1. Mysql中的事務
    mysql中的事務自動提交,一個sql語句就是一個事務。
    start transaction 開啟事務
    rollback 回滾事務
    commit 提交事務:事務提交後,不能恢復
    (注)
    1.commit操作就是用較高效率的方式將事務操作記錄到磁碟上,然後資料庫在達到最有效條件的時候呼叫DBRW(DBWR是資料庫寫程序)將資料寫入資料檔案,期間不影響資料的一致性。
    2.commit會觸發lgwr程序,此程序會將redo log buffer 裡的與commit的事務相關的redo record寫入log file。
    關閉自動提交事務:set autocommit = off/ set autocommit = 0;

  2. oracle中的事務
    oracle中的事務預設是不自動提交的,需要在執行sql語句之後敲commit提交。

事務的特性 (ACID)

  1. 原子性
    指的是事務是一個不可拆分的整體,要麼事務中所有的操作都發生,要麼都不發生。
  2. 一致性
    事務前後的資料完整性必須保持一致。(這裡可能有點疑問)
    舉個例子。當前的你賬戶上面有500,你去買一個300的東西(事務1),但是在事務執行的過程中,還沒執行完,你又買了一個400的東西(事務2)。這就會導致兩個事務操作的狀態是不一致的。本來-400這個應該是在500-300後的200這個狀態上面的,但是變成了500上面操作。由一開始的500,變成兩個狀態,200和100。違反了一致性,一致性就是隻能從500變成100或者200就好。
  3. 隔離性
    事務的隔離性就是多個使用者同時訪問資料的時候,一個使用者的事務不能被其他使用者的事務干擾,多個併發事務之間資料需要相互隔離。隔離性可以避免產生“髒讀”。
  4. 永續性
    永續性是指事務一旦被提交,就會永久的改變資料庫的資料。

事務隔離級別

事務如果不考慮隔離性,則會產生下列問題

  • 髒讀
    指一個使用者讀取到的資料正在被另一個使用者操作。當另一個使用者執行回滾操作的時候,前一個使用者讀取的資料發生變化。
  • 不可重複讀
    在一個事務先後兩次讀取的資料情況不一樣,第二次讀取到另一個事務以及提交資料(強調資料記錄變化 update )
  • 虛讀或幻讀:在一個事務中,第二次讀取發生資料記錄數的不同 ,讀取到另一個事務已經提交資料 (強調資料記錄變化 insert )

可以使用序列化來避免這些問題。
Serializable:序列化就是將物件序列化成一個可傳輸,儲存的介質。也就是說儲存記憶體中的物件,存到臨時儲存區或永續性儲存區。(感覺相當於提交事務)
這裡寫連結內容

事務的丟失更新問題

多個事務同時更新,會產生覆蓋。丟失更新的資料。

解決:

悲觀鎖:select * from table lock in share mode(讀鎖,共享鎖)
select * from table for update (寫鎖,排他鎖)

mysql資料庫內部提供兩種常用 鎖機制:共享鎖(讀鎖)和排它鎖(寫鎖)
允許一張資料表中資料記錄,新增多個共享鎖,新增共享鎖記錄,對於其他事務可讀不可寫的
一張資料表中資料記錄,只能新增一個排它鎖,在新增排它鎖的資料 不能再新增其他共享鎖和排它鎖的 ,
對於其他事物可讀不可寫的

樂觀鎖:
採用記錄的版本欄位,來判斷記錄是否修改過 ————– timestamp
timestamp 可以自動更新
create table product (
id int,
name varchar(20),
updatetime timestamp
);

每次修改都會判斷更新時間是否與之前的一樣,一樣則更新,不一樣則事務提交失敗