<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 42,comments - 83,trackbacks - 0

            這幾天做transaction recover測試的時候,發現個很難理解的問題。
            
            具體問題場景如下:
            1:一個standby client程序,調用userTransaction.begin()后,順序操作兩個XA resource,這兩個resource為同一個Oracle database, 不過操作使用的connection來源于不同的data source。connection1向表test中插入一條數據,connection2向表test1中插入一條數據。最后執行userTransaction.commit()。
            2:userTransaction.commit()執行的時,需要執行兩階段提交,首先是global prepare,如果所有的resource都prepare ok的話,weblogic這時候會寫入tx record(寫入到tlog中)。然后執行global commit。測試過程中,在執行完global prepare后,在global commit處設定break point,然后停止database。數據庫停止后,去除global commit的break point, 此時weblogic需要向每個resource發出commit指令。因為部分resource此時是unavailable的,weblogic無法收到每個resource commit完成的響應,該tx信息會一直保存在tlog中,等待server重起的時候recover。
            3:按照正常邏輯global prepare完成后,該tx應該是只能commit,而不能rollback的,但在測試中發現,weblogic在recover的時候 ,會去rollback這個tx。

            下面是測試中記錄的數據信息。
             1:數據庫重起后,weblogic重起前,可以看到database中該tx信息如下:

            2:weblogic tlog中的信息,
    +------------------------------------------------------------------------------+
    | Transaction Log Dump |                                                       |
    +------------------------------------------------------------------------------+

    | Class Name = weblogic.transaction.internal.ResourceCheckpoint                |

    | Object = ResourceCheckpoint={OracelXADS, OracleXADS1}                        |

    +------------------------------------------------------------------------------+


            3:weblogic重起后,可以看到該tx branch在recover的時候被rollback,
            ####<Nov 21, 2008 11:20:33 AM CST> <Debug> <debug@XAResourceDescriptor> <why> <AdminServer> <[STANDBY] ExecuteThread: '4' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1227237633250> <000000> <to rollback tx, xid: BEA1-0000669563242B7A1CFC-4F726163656C58414453> 
            這個信息是我debug出來的,weblogic會依據xid(branchid),調用XAResource.rollback(Xid xid), 將該事務分支rollback?,F在看到的問題是:4F7261636C655841445331分支已經commit了,我們調用XAResource.rollback(Xid xid), rollback 0000669563242B7A1CFC-4F726163656C58414453后,4F7261636C655841445331怎么也被rollback了呢? 

      Note: 在weblogic recover的時候,XAResource需要執行后端的存儲過程,如果對應用戶沒有權限的話,weblogic server的日志里能看到如下信息:

    ####<Nov 20, 2008 7:12:24 PM CST> <Debug> <JDBCDriverLogging> <why> <AdminServer> <[STANDBY] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1227179544296> <000000> <SQLException: SQLState(65000) vendor code(6550)>
    ####<Nov 20, 2008 7:12:24 PM CST> <Debug> <JDBCDriverLogging> <why> <AdminServer> <[STANDBY] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1227179544296> <000000> <java.sql.SQLException: ORA-06550: line 1, column 7:
    PLS-00201: identifier 'SYS.DBMS_SYSTEM' must be declared
    ORA-06550: line 1, column 7:
    PL/SQL: Statement ignored

            碰到這種錯誤的時候,執行如下的SQL:grant execute on sys.dbms_system to system;

    ########################后續#####################

            經過半天的調查,終于找到問題的原因了。問題出在Oracle XA Driver上,我們使用來自于不同datasource的XAConnection對同一個database操作的時候,我們把它們當作兩個事務分支,分支ID如下:
    Branch 1: 4F7261636C655841445331
    Branch 2: 4F7261636C65584144533
    如果這兩個事務分支分別指向不同的database的話,global prepare時,xaResource.prepare()的結果應該為OK(prepare的時候,database工作正常)。而我們上面的測試中,因為操作的是統一database,其prepare的結果分別是:OK, READ_ONLY(數據庫端認為該TX branch對應的操作不涉及數據修改)。返回READ_ONLY的時候,因為database認為該 tx branch不涉及數據修改,所以直接將它commit了。這也就解釋了上面的疑問,global commit沒有執行的時候,怎么就有tx branch被commit了。

            下面再看看,為什么tlog中只能看到check point信息,而沒有記錄tx信息。在global prepare中,所有的參與該tx的resource的prepare結果返回后,weblogic需要根據vote結果決定進行global commit or global rollback。如果所有resource prepare都沒問題的話,則將進行global commit。而在global commit之前,weblogic需要判斷是否要將該tx信息記錄到tlog中,而是記錄tx的依據就是vote結果為0(OK)的resource個數是否大于1。大于1,則記入tlog,否則不做記錄。我們上面的測試中,因為只涉及兩個resource,而這兩個resource的vote結果分別為:0(OK), 3(READ_ONLY),所以該tx信息沒有被記錄到tlog中。

            weblogic在recover的時候,首先檢查tlog中的tx信息,如果存在tx,則讀取tx信息,并將該tx放入到當前server的txMap中。然后調用xaResource.recover(),該方法的執行結果是,resource manager(如database, jms server)返回自己手里的pending transaction的xid list。 weblogic遍歷該xid list,如果發現某個xid在當前txMap中,則忽略它(該tx將會被其他線程commit),那些不在txMap中的xid將會被rollback,通過xaResource.rollback(Xid xid)實現。在我們上面的測試中,因為tx沒有被記錄到tlog中,所以weblogic在recover的時候會將database返回的xid: 0000669563242B7A1CFC-4F726163656C58414453 rollback。由于Oracle Driver的特殊處理,兩個connection上的兩個tx branch被合并成了一個branch(另一個被它認為是個READ_ONLY),所以在rollback的時候,test, test1兩表上的數據都被rollback了。

            在使用兩個不同的database測試中,能夠看到tlog中的tx信息,weblogic server重啟后,也能看到tx的commit。tlog信息如下:


            最后再說一下weblogic執行global prepare時,resource的prepare順序:
            1:remote xa resource
            2:local xa resource
            3:non-XA resource( LLR,對于Emulate 2PC的nonXA reosurce, 它的prepare結果直接就是OK,其實是個假prepare)
            所謂的remote, local不是只resource managed的位置,而是指resource對應的coordinator的位置。
    posted on 2008-11-23 19:55 走走停停又三年 閱讀(2338) 評論(0)  編輯  收藏 所屬分類: Weblogic
    主站蜘蛛池模板: 亚洲视频一区在线播放| jzzijzzij在线观看亚洲熟妇| 免费在线看v网址| 亚洲AV永久无码精品网站在线观看| 四虎永久成人免费| 国产精品免费无遮挡无码永久视频| 亚洲另类古典武侠| 亚洲国产精品成人久久蜜臀| 免费无码成人AV在线播放不卡| 亚洲第一男人天堂| 亚洲无av在线中文字幕| 一个人看的www在线观看免费| 暖暖免费中文在线日本| 亚洲综合免费视频| 亚洲中文字幕无码专区| 免费做爰猛烈吃奶摸视频在线观看 | 一二三四视频在线观看中文版免费| 亚洲精品无码永久在线观看男男| 国产亚洲?V无码?V男人的天堂| 亚洲人成免费电影| 国产精品福利片免费看| 国产精品亚洲午夜一区二区三区 | 亚洲精品自在在线观看| 成人免费视频88| 免费无码中文字幕A级毛片| 污污免费在线观看| 97久久国产亚洲精品超碰热| 亚洲中久无码永久在线观看同| 好吊妞在线新免费视频| 久久w5ww成w人免费| 一级成人毛片免费观看| 亚洲欧洲日产国码久在线| 亚洲第一福利网站| 曰韩亚洲av人人夜夜澡人人爽| 日本一道本高清免费| 成人免费视频69| 久久国产免费一区| 国产免费久久久久久无码| 全黄A免费一级毛片| 亚洲av无码专区在线观看亚| 亚洲福利电影一区二区?|