閱讀165 返回首頁    go 阿裏雲 go 技術社區[雲棲]


acid

ACID,指數據庫事務正確執行的四個基本要素的縮寫。包含:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。一個支持事務(Transaction)的數據庫係統,必需要具有這四種特性,否則在事務過程(Transaction processing)當中無法保證數據的正確性,交易過程極可能達不到交易方的要求。

  原子性
  整個事務中的所有操作,要麼全部完成,要麼全部不完成,不可能停滯在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
  一致性
  在事務開始之前和事務結束以後,數據庫的完整性約束沒有被破壞。
  隔離性
  兩個事務的執行是互不幹擾的,一個事務不可能看到其他事務運行時,中間某一時刻的數據。
  持久性
  在事務完成以後,該事務所對數據庫所作的更改便持久的保存在數據庫之中,並不會被回滾。
  由於一項操作通常會包含許多子操作,而這些子操作可能會因為硬件的損壞或其他因素產生問題,要正確實現ACID並不容易。ACID建議數據庫將所有需要更新 以及修改的資料一次操作完畢,但實際上並不可行。
  目前主要有兩種方式實現ACID:第一種是Write ahead logging,也就是日誌式的方式。第二種是Shadow paging。

回滾

 刪除由一個或多個部分完成的事務執行的更新。為在應用程序、數據庫或係統錯誤後還原數據庫的完整性,需要使用回滾。
  回滾泛指程序更新失敗, 返回上一次正確狀態的行為。
  回滾對程序員意味著非常嚴重的失誤。因為回滾次數往往與程序員的薪金直接聯係。主流互聯網公司通常都將回滾定位為最嚴重的事故。
  回滾與恢複有本質的區別。
  而升級回滾則是指因升級中所發生的意外而自動回滾

1        事務並發處理(麵試的意義更大)

a)  事務:ACID

         i.   Atomic ConsistencyItegrity Durability

b)  事務並發時可能出現的問題:

第一類丟失更新(Lost Update)

時間

取款事務A

存款事務B

T1

開始事務

 

T2

 

開始事務

T3

查詢賬戶餘額為1000元

 

T4

 

查詢賬戶餘額為1000元

T5

 

匯入100元把餘額改為1100元

T6

 

提交事務

T7

取出100元把餘額改為900 元

 

T8

撤銷事務

 

T9

餘額恢複為1000元(丟失更新)

 

   

    dirtyread髒讀(讀到了另一個事務在處理中還未提交的數據)

時間

取款事務A

存款事務B

T1

開始事務

 

T2

 

開始事務

T3

 

查詢賬戶餘額為1000元

T4

 

匯入100元把餘額改為1100元

T5

查詢賬戶餘額為1100元(讀取髒數據)

 

T6

 

回滾

T7

取款1100

 

T8

提交事務失敗

 

 

    non-repeatableread 不可重複讀

時間

取款事務A

存款事務B

T1

開始事務

 

T2

 

開始事務

T3

查詢賬戶餘額為1000元

 

T5

 

匯入100元把餘額改為1100元

T5

 

提交事務

T6

查詢帳戶餘額為1100元

 

T8

提交事務

 

 

    secondlost update problem 第二類丟失更新(不可重複讀的特殊情況)

時間

取款事務A

存款事務B

T1

 

開始事務

T2

開始事務

 

T3

 

查詢賬戶餘額為1000元

T4

查詢賬戶餘額為1000元

 

T5

 

取出100元把餘額改為900元

T6

 

提交事務

T7

匯入100元

 

T8

提交事務

 

T9

把餘額改為1100元(丟失更新)

 

 

    phantomread 幻讀

時間

查詢學生事務A

插入新學生事務B

T1

開始事務

 

T2

 

開始事務

T3

查詢學生為10人

 

T4

 

插入1個學生

T5

查詢學生為11人

 

T6

 

提交事務

T7

提交事務

 

c)  數據庫的事務隔離機製

        i.   查看 java.sql.Connection 文檔

       ii.   1:read-uncommitted  2:read-committed  4:repeatable read  8:serializable(數字代表對應值)

為什麼取值要使用 1 2 4 8而不是 1 2 3 4

1=0000  2=0010 4=01008=1000(位移計算效率高)

1.     隻要數據庫支持事務,就不可能出現第一類丟失更新

2.     read-uncommitted(允許讀取未提交的數據) 會出現dirty read, phantom-read,

non-repeatableread 問題

3.     read-commited(讀取已提交的數據項目中一般都使用這個)不會出現dirty read,因為隻有另

一個事務提交才會讀出來結果,但仍然會出現 non-repeatable read 和 phantom-read

   使用read-commited機製可用悲觀鎖樂觀鎖來解決non-repeatable read phantom-read問題

4.     repeatableread(事務執行中其他事務無法執行修改或插入操作    較安全)

5.     serializable解決一切問題(順序執行事務不並發,實際中很少用)

d)  設定hibernate的事務隔離級別(使用hibernate.connection.isolation配置取值1、2、4、8)

        i.   hibernate.connection.isolation= 2(如果不設 默認依賴數據庫本身的級別

       ii.   用悲觀鎖解決repeatable read的問題(依賴於數據庫的鎖)

(詳見項目 hibernate_3100_Hibernate_Concurrency_Pessimistic_Lock)

1.     select ... for update

2.      使用另一種load方法--load(xx.class , i , LockMode.Upgrade)

a) LockMode.None無鎖的機製,Transaction結束時,切換到此模式

b) LockMode.read在査詢的時候hibernate會自動獲取鎖

c) LockMode.write insert  updatehibernate 會自動獲取鎖

d) 以上3種鎖的模式,是hibernate內部使用的(不需要設)

e) LockMode.UPGRADE_NOWAIT是 ORACLE 支持的鎖的方式

e)  Hibernate(JPA)樂觀鎖定(ReadCommitted)

(詳見項目hibernate_3200_Hibernate_Concurrency_Optimistic_Lock)

實體類中增加version屬性(數據庫也會對應生成該字段,初始值為0),並在其get方法前加

@Version注解,則在操作過程中沒更新一次該行數據則version值加1,即可在事務提交前判斷該數據是否被其他事務修改過.

            @Version

時間

轉賬事務A

取款事務B

T1

 

開始事務

T2

開始事務

 

T3

查詢學生為10人

查詢賬戶餘額為1000 version=0

T4

查詢賬戶餘額為1000 version=0

 

T5

 

取出100 把餘額改為900 version=1

T6

 

提交事務

T7

匯入100元

 

T8

提交事務 ? version>0

throw Exception

 

T9

把餘額改為1100元(丟失更新)

 

 


最後更新:2017-04-02 16:48:17

  上一篇:go c語言 王者歸來
  下一篇:go tomcat6.0支持 SSI相關配置