學習園地

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            3 Posts :: 14 Stories :: 0 Comments :: 0 Trackbacks

          一、Propagation (事務的傳播屬性)

          Propagation :  key屬性確定代理應該給哪個方法增加事務行為。這樣的屬性最重要的部份是傳播行為。有以下選項可供使用:  

          PROPAGATION_REQUIRED--支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。

          PROPAGATION_SUPPORTS--支持當前事務,如果當前沒有事務,就以非事務方式執行。

          PROPAGATION_MANDATORY--支持當前事務,如果當前沒有事務,就拋出異常。

          PROPAGATION_REQUIRES_NEW--新建事務,如果當前存在事務,把當前事務掛起。

          PROPAGATION_NOT_SUPPORTED--以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

          PROPAGATION_NEVER--以非事務方式執行,如果當前存在事務,則拋出異常。

          1: PROPAGATION_REQUIRED

          加入當前正要執行的事務不在另外一個事務里,那么就起一個新的事務

          比如說,ServiceB.methodB的事務級別定義為PROPAGATION_REQUIRED, 那么由于執行ServiceA.methodA的時候,

          ServiceA.methodA已經起了事務,這時調用ServiceB.methodB,ServiceB.methodB看到自己已經運行在ServiceA.methodA

          的事務內部,就不再起新的事務。而假如ServiceA.methodA運行的時候發現自己沒有在事務中,他就會為自己分配一個事務。

          這樣,在ServiceA.methodA或者在ServiceB.methodB內的任何地方出現異常,事務都會被回滾。即使ServiceB.methodB的事務已經被

          提交,但是ServiceA.methodA在接下來fail要回滾,ServiceB.methodB也要回滾

          2: PROPAGATION_SUPPORTS

          如果當前在事務中,即以事務的形式運行,如果當前不再一個事務中,那么就以非事務的形式運行

          3: PROPAGATION_MANDATORY

          必須在一個事務中運行。也就是說,他只能被一個父事務調用。否則,他就要拋出異常

          4: PROPAGATION_REQUIRES_NEW

          這個就比較繞口了。 比如我們設計ServiceA.methodA的事務級別為PROPAGATION_REQUIRED,ServiceB.methodB的事務級別為PROPAGATION_REQUIRES_NEW,

          那么當執行到ServiceB.methodB的時候,ServiceA.methodA所在的事務就會掛起,ServiceB.methodB會起一個新的事務,等待ServiceB.methodB的事務完成以后,

          他才繼續執行。他與PROPAGATION_REQUIRED 的事務區別在于事務的回滾程度了。因為ServiceB.methodB是新起一個事務,那么就是存在

          兩個不同的事務。如果ServiceB.methodB已經提交,那么ServiceA.methodA失敗回滾,ServiceB.methodB是不會回滾的。如果ServiceB.methodB失敗回滾,

          如果他拋出的異常被ServiceA.methodA捕獲,ServiceA.methodA事務仍然可能提交。

          5: PROPAGATION_NOT_SUPPORTED

          當前不支持事務。比如ServiceA.methodA的事務級別是PROPAGATION_REQUIRED ,而ServiceB.methodB的事務級別是PROPAGATION_NOT_SUPPORTED ,

          那么當執行到ServiceB.methodB時,ServiceA.methodA的事務掛起,而他以非事務的狀態運行完,再繼續ServiceA.methodA的事務。

          6: PROPAGATION_NEVER

          不能在事務中運行。假設ServiceA.methodA的事務級別是PROPAGATION_REQUIRED, 而ServiceB.methodB的事務級別是PROPAGATION_NEVER ,

          那么ServiceB.methodB就要拋出異常了。

          7: PROPAGATION_NESTED

          理解Nested的關鍵是savepoint。他與PROPAGATION_REQUIRES_NEW的區別是,PROPAGATION_REQUIRES_NEW另起一個事務,將會與他的父事務相互獨立,

          而Nested的事務和他的父事務是相依的,他的提交是要等和他的父事務一塊提交的。也就是說,如果父事務最后回滾,他也要回滾的。

          而Nested事務的好處是他有一個savepoint。

          *****************************************

          ServiceA {

          /**

          * 事務屬性配置為 PROPAGATION_REQUIRED

          */

          void methodA() {

          try {

          //savepoint

          ServiceB.methodB(); //PROPAGATION_NESTED 級別

          } catch (SomeException) {

          // 執行其他業務, 如 ServiceC.methodC();

          }

          }

          }

          ********************************************

          也就是說ServiceB.methodB失敗回滾,那么ServiceA.methodA也會回滾到savepoint點上,ServiceA.methodA可以選擇另外一個分支,比如

          ServiceC.methodC,繼續執行,來嘗試完成自己的事務。

          但是這個事務并沒有在EJB標準中定義。

          二、Isolation Level(事務隔離等級):

          1、Serializable:最嚴格的級別,事務串行執行,資源消耗最大;

          2、REPEATABLE READ:保證了一個事務不會修改已經由另一個事務讀取但未提交(回滾)的數據。避免了“臟讀取”和“不可重復讀取”的情況,但是帶來了更多的性能損失。

          3、READ COMMITTED:大多數主流數據庫的默認事務等級,保證了一個事務不會讀到另一個并行事務已修改但未提交的數據,避免了“臟讀取”。該級別適用于大多數系統。

          4、Read Uncommitted:保證了讀取過程中不會讀取到非法數據。隔離級別在于處理多事務的并發問題。

          我們知道并行可以提高數據庫的吞吐量和效率,但是并不是所有的并發事務都可以并發運行,這需要查看數據庫教材的可串行化條件判斷了。

          這里就不闡述。

          我們首先說并發中可能發生的3中不討人喜歡的事情

          1: Dirty reads--讀臟數據。也就是說,比如事務A的未提交(還依然緩存)的數據被事務B讀走,如果事務A失敗回滾,會導致事務B所讀取的的數據是錯誤的。

          2: non-repeatable reads--數據不可重復讀。比如事務A中兩處讀取數據-total-的值。在第一讀的時候,total是100,然后事務B就把total的數據改成 200,事務A再讀一次,結果就發現,total竟然就變成200了,造成事務A數據混亂。

          3: phantom reads--幻象讀數據,這個和non-repeatable reads相似,也是同一個事務中多次讀不一致的問題。但是non-repeatable reads的不一致是因為他所要取的數據集被改變了(比如total的數據),但是phantom reads所要讀的數據的不一致卻不是他所要讀的數據集改變,而是他的條件數據集改變。比如Select account.id where account.name="ppgogo*",第一次讀去了6個符合條件的id,第二次讀取的時候,由于事務b把一個帳號的名字由"dd"改成"ppgogo1",結果取出來了7個數據。

           

            Dirty reads non-repeatable reads phantom reads
          Serializable 不會 不會 不會
          REPEATABLE READ 不會 不會
          READ COMMITTED 不會
          Read Uncommitted

           

           

          三、readOnly

          事務屬性中的readOnly標志表示對應的事務應該被最優化為只讀事務。

          這是一個最優化提示。在一些情況下,一些事務策略能夠起到顯著的最優化效果,例如在使用Object/Relational映射工具(如:Hibernate或TopLink)時避免dirty checking(試圖“刷新”)。

          四、Timeout

          在事務屬性中還有定義“timeout”值的選項,指定事務超時為幾秒。在JTA中,這將被簡單地傳遞到J2EE服務器的事務協調程序,并據此得到相應的解釋

           

          spring里面事務的傳播屬性和事務隔離級別

           

          一、Propagation (事務的傳播屬性)

          Propagation :  key屬性確定代理應該給哪個方法增加事務行為。這樣的屬性最重要的部份是傳播行為。有以下選項可供使用:PROPAGATION_REQUIRED--支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。

          PROPAGATION_SUPPORTS--支持當前事務,如果當前沒有事務,就以非事務方式執行。

          PROPAGATION_MANDATORY--支持當前事務,如果當前沒有事務,就拋出異常。

          PROPAGATION_REQUIRES_NEW--新建事務,如果當前存在事務,把當前事務掛起。

          PROPAGATION_NOT_SUPPORTED--以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

          PROPAGATION_NEVER--以非事務方式執行,如果當前存在事務,則拋出異常。

          1: PROPAGATION_REQUIRED

          加入當前正要執行的事務不在另外一個事務里,那么就起一個新的事務

          比如說,ServiceB.methodB的事務級別定義為PROPAGATION_REQUIRED, 那么由于執行ServiceA.methodA的時候,

          ServiceA.methodA已經起了事務,這時調用ServiceB.methodB,ServiceB.methodB看到自己已經運行在ServiceA.methodA

          的事務內部,就不再起新的事務。而假如ServiceA.methodA運行的時候發現自己沒有在事務中,他就會為自己分配一個事務。

          這樣,在ServiceA.methodA或者在ServiceB.methodB內的任何地方出現異常,事務都會被回滾。即使ServiceB.methodB的事務已經被

          提交,但是ServiceA.methodA在接下來fail要回滾,ServiceB.methodB也要回滾

          2: PROPAGATION_SUPPORTS

          如果當前在事務中,即以事務的形式運行,如果當前不再一個事務中,那么就以非事務的形式運行

          3: PROPAGATION_MANDATORY

          必須在一個事務中運行。也就是說,他只能被一個父事務調用。否則,他就要拋出異常

          4: PROPAGATION_REQUIRES_NEW

          這個就比較繞口了。 比如我們設計ServiceA.methodA的事務級別為PROPAGATION_REQUIRED,ServiceB.methodB的事務級別為PROPAGATION_REQUIRES_NEW,

          那么當執行到ServiceB.methodB的時候,ServiceA.methodA所在的事務就會掛起,ServiceB.methodB會起一個新的事務,等待ServiceB.methodB的事務完成以后,

          他才繼續執行。他與PROPAGATION_REQUIRED 的事務區別在于事務的回滾程度了。因為ServiceB.methodB是新起一個事務,那么就是存在

          兩個不同的事務。如果ServiceB.methodB已經提交,那么ServiceA.methodA失敗回滾,ServiceB.methodB是不會回滾的。如果ServiceB.methodB失敗回滾,

          如果他拋出的異常被ServiceA.methodA捕獲,ServiceA.methodA事務仍然可能提交。

          5: PROPAGATION_NOT_SUPPORTED

          當前不支持事務。比如ServiceA.methodA的事務級別是PROPAGATION_REQUIRED ,而ServiceB.methodB的事務級別是PROPAGATION_NOT_SUPPORTED ,

          那么當執行到ServiceB.methodB時,ServiceA.methodA的事務掛起,而他以非事務的狀態運行完,再繼續ServiceA.methodA的事務。

          6: PROPAGATION_NEVER

          不能在事務中運行。假設ServiceA.methodA的事務級別是PROPAGATION_REQUIRED, 而ServiceB.methodB的事務級別是PROPAGATION_NEVER ,

          那么ServiceB.methodB就要拋出異常了。

          7: PROPAGATION_NESTED

          理解Nested的關鍵是savepoint。他與PROPAGATION_REQUIRES_NEW的區別是,PROPAGATION_REQUIRES_NEW另起一個事務,將會與他的父事務相互獨立,

          而Nested的事務和他的父事務是相依的,他的提交是要等和他的父事務一塊提交的。也就是說,如果父事務最后回滾,他也要回滾的。

          而Nested事務的好處是他有一個savepoint。

          *****************************************

          ServiceA {

          /**

          * 事務屬性配置為 PROPAGATION_REQUIRED

          */

          void methodA() {

          try {

          //savepoint

          ServiceB.methodB(); //PROPAGATION_NESTED 級別

          } catch (SomeException) {

          // 執行其他業務, 如 ServiceC.methodC();

          }

          }

          }

          ********************************************

          也就是說ServiceB.methodB失敗回滾,那么ServiceA.methodA也會回滾到savepoint點上,ServiceA.methodA可以選擇另外一個分支,比如

          ServiceC.methodC,繼續執行,來嘗試完成自己的事務。

          但是這個事務并沒有在EJB標準中定義。

          二、Isolation Level(事務隔離等級):

          1、Serializable:最嚴格的級別,事務串行執行,資源消耗最大;

          2、REPEATABLE READ:保證了一個事務不會修改已經由另一個事務讀取但未提交(回滾)的數據。避免了“臟讀取”和“不可重復讀取”的情況,但是帶來了更多的性能損失。

          3、READ COMMITTED:大多數主流數據庫的默認事務等級,保證了一個事務不會讀到另一個并行事務已修改但未提交的數據,避免了“臟讀取”。該級別適用于大多數系統。

          4、Read Uncommitted:保證了讀取過程中不會讀取到非法數據。隔離級別在于處理多事務的并發問題。

          我們知道并行可以提高數據庫的吞吐量和效率,但是并不是所有的并發事務都可以并發運行,這需要查看數據庫教材的可串行化條件判斷了。

          這里就不闡述。

          我們首先說并發中可能發生的3中不討人喜歡的事情

          1: Dirty reads--讀臟數據。也就是說,比如事務A的未提交(還依然緩存)的數據被事務B讀走,如果事務A失敗回滾,會導致事務B所讀取的的數據是錯誤的。

          2: non-repeatable reads--數據不可重復讀。比如事務A中兩處讀取數據-total-的值。在第一讀的時候,total是100,然后事務B就把total的數據改成 200,事務A再讀一次,結果就發現,total竟然就變成200了,造成事務A數據混亂。

          3: phantom reads--幻象讀數據,這個和non-repeatable reads相似,也是同一個事務中多次讀不一致的問題。但是non-repeatable reads的不一致是因為他所要取的數據集被改變了(比如total的數據),但是phantom reads所要讀的數據的不一致卻不是他所要讀的數據集改變,而是他的條件數據集改變。比如Select account.id where account.name="ppgogo*",第一次讀去了6個符合條件的id,第二次讀取的時候,由于事務b把一個帳號的名字由"dd"改成"ppgogo1",結果取出來了7個數據。

           

            Dirty reads non-repeatable reads phantom reads
          Serializable 不會 不會 不會
          REPEATABLE READ 不會 不會
          READ COMMITTED 不會
          Read Uncommitted

           

           

          三、readOnly

          事務屬性中的readOnly標志表示對應的事務應該被最優化為只讀事務。

          這是一個最優化提示。在一些情況下,一些事務策略能夠起到顯著的最優化效果,例如在使用Object/Relational映射工具(如:Hibernate或TopLink)時避免dirty checking(試圖“刷新”)。

          四、Timeout

          在事務屬性中還有定義“timeout”值的選項,指定事務超時為幾秒。在JTA中,這將被簡單地傳遞到J2EE服務器的事務協調程序,并據此得到相應的解釋

           

           

          20110112

          數據庫提供了四種事務隔離級別, 不同的隔離級別采用不同的鎖類開來實現. 

          在四種隔離級別中, Serializable的級別最高, Read Uncommited級別最低. 

          大多數數據庫的默認隔離級別為: Read Commited,如Sql Server , Oracle. 

          少數數據庫默認的隔離級別為Repeatable Read, 如MySQL InnoDB存儲引擎 

          即使是最低的級別,也不會出現 第一類 丟失 更新問題 .  

          1. 臟讀(事務沒提交,提前讀取) :臟讀就是指當一個事務正在訪問數據,并且對數據進行了修改,而這種修改還沒有提交到數據庫中,這時,另外一個事務也訪問這個數據,然后使用了這個數據。 

          2. 不可重復讀(兩次讀的不一致) :是指在一個事務內,多次讀同一數據。在這個事務還沒有結束時,另外一個事務也訪問該同一數據。那么,在第一個事務中的兩次讀數據之間,由于第二個事務的修改,那么第一個事務兩次讀到的的數據可能是不一樣的。這樣就發生了在一個事務內兩次讀到的數據是不一樣的,因此稱為是不可重復讀。例如,一個編輯人員兩次讀取同一文檔,但在兩次讀取之間,作者重寫了該文檔。當編輯人員第二次讀取文檔時,文檔已更改。原始讀取不可重復。如果只有在作者全部完成編寫后編輯人員才可以讀取文檔,則可以避免該問題。 
          3. 幻讀 : 是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那么,以后就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。例如,一個編輯人員更改作者提交的文檔,但當生產部門將其更改內容合并到該文檔的主復本時,發現作者已將未編輯的新材料添加到該文檔中。如果在編輯人員和生產部門完成對原始文檔的處理之前,任何人都不能將新材料添加到文檔中,則可以避免該問題。 
          4. 第一類更新丟失(回滾丟失)  
            當2個事務更新相同的數據源,如果第一個事務被提交,而另外一個事務卻被撤銷,那么會連同第一個事務所做的跟新也被撤銷。也就是說第一個事務做的跟新丟失了。 
          5. 第二類更新丟失(覆蓋丟失)  
            第二類更新丟失實在實際應用中經常遇到的并發問題,他和不可重復讀本質上是同一類并發問題,通常他被看做不可重復讀的特例:當2個或這個多個事務查詢同樣的記錄然后各自基于最初的查詢結果更新該行時,會造成第二類丟失更新。因為每個事務都不知道不知道其他事務的存在,最后一個事務對記錄做的修改將覆蓋其他事務對該記錄做的已提交的跟新... 
          補充 : 基于元數據的 Spring 聲明性事務 : 

          Isolation 屬性一共支持五種事務設置,具體介紹如下: 

          l          DEFAULT 使用數據庫設置的隔離級別 ( 默認 ) ,由 DBA 默認的設置來決定隔離級別 . 

          l          READ_UNCOMMITTED 會出現臟讀、不可重復讀、幻讀 ( 隔離級別最低,并發性能高 )

          l          READ_COMMITTED  會出現不可重復讀、幻讀問題(鎖定正在讀取的行) 

          l          REPEATABLE_READ 會出幻讀(鎖定所讀取的所有行) 

          l          SERIALIZABLE 保證所有的情況不會發生(鎖表) 

          不可重復讀的重點是修改 : 
          同樣的條件 ,   你讀取過的數據 ,   再次讀取出來發現值不一樣了 
          幻讀的重點在于新增或者刪除 
          同樣的條件 ,   第 1 次和第 2 次讀出來的記錄數不一樣 

          posted on 2014-03-26 11:00 丘比特 閱讀(117) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 辽源市| 阿克| 丰台区| 荥阳市| 岳阳市| 句容市| 阳原县| 岳池县| 溧水县| 湘潭市| 礼泉县| 大洼县| 文成县| 桂阳县| 中山市| 仁寿县| 广灵县| 会昌县| 溆浦县| 衡阳市| 米易县| 安龙县| 崇左市| 磐安县| 沾化县| 通州区| 夏河县| 鄂州市| 东辽县| 琼海市| 和静县| 青州市| 中西区| 中牟县| 岗巴县| 廊坊市| 鹤山市| 托克托县| 泸州市| 英吉沙县| 阿鲁科尔沁旗|