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

            下面是測試中記錄的數(shù)據(jù)信息。
             1:數(shù)據(jù)庫重起后,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會依據(jù)xid(branchid),調(diào)用XAResource.rollback(Xid xid), 將該事務(wù)分支rollback。現(xiàn)在看到的問題是:4F7261636C655841445331分支已經(jīng)commit了,我們調(diào)用XAResource.rollback(Xid xid), rollback 0000669563242B7A1CFC-4F726163656C58414453后,4F7261636C655841445331怎么也被rollback了呢? 

      Note: 在weblogic recover的時候,XAResource需要執(zhí)行后端的存儲過程,如果對應(yīng)用戶沒有權(quán)限的話,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

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

    ########################后續(xù)#####################

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

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

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

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


            最后再說一下weblogic執(zhí)行g(shù)lobal prepare時,resource的prepare順序:
            1:remote xa resource
            2:local xa resource
            3:non-XA resource( LLR,對于Emulate 2PC的nonXA reosurce, 它的prepare結(jié)果直接就是OK,其實是個假prepare)
            所謂的remote, local不是只resource managed的位置,而是指resource對應(yīng)的coordinator的位置。
    posted on 2008-11-23 19:55 走走停停又三年 閱讀(2332) 評論(0)  編輯  收藏 所屬分類: Weblogic
    主站蜘蛛池模板: 国产又黄又爽又猛免费app| 女性无套免费网站在线看| 久久久久亚洲AV片无码下载蜜桃| 精品无码无人网站免费视频| 亚洲综合在线一区二区三区| 亚洲一区二区三区在线播放 | 秋霞人成在线观看免费视频| 亚洲噜噜噜噜噜影院在线播放 | 亚洲黄色网站视频| 国产免费人视频在线观看免费| 国产精品网站在线观看免费传媒| 激情综合亚洲色婷婷五月APP| 国产中文在线亚洲精品官网| 青草草色A免费观看在线| 99视频在线观看免费| 久久乐国产综合亚洲精品| 国产av天堂亚洲国产av天堂| 全免费一级毛片在线播放| 国产午夜精品久久久久免费视 | 中文字幕a∨在线乱码免费看 | 亚洲人成影院在线| 免费一级毛片免费播放| 免费成人激情视频| 99re6在线视频精品免费| 亚洲风情亚Aⅴ在线发布| 少妇中文字幕乱码亚洲影视| 亚洲狠狠爱综合影院婷婷| 皇色在线视频免费网站| 九九美女网站免费| 深夜福利在线视频免费| 亚洲综合激情五月丁香六月 | 免费a级毛片无码a∨免费软件| 亚洲精品国产第一综合99久久| 亚洲综合激情另类小说区| 国产亚洲福利精品一区| 亚洲国产小视频精品久久久三级| 99热在线精品免费全部my| 99久9在线|免费| 国产午夜无码精品免费看动漫| 成年大片免费高清在线看黄| 亚洲AⅤ男人的天堂在线观看|