<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

            某些時(shí)候,在weblogic執(zhí)行XA操作的時(shí)候,我們會碰到如下的錯(cuò)誤:
            java.sql.SQLException: Unexpected exception while enlisting XAConnection java.sql.SQLException: XA error: XAER_NOTA : The XID is not valid start() failed on resource 'weblogic.jdbc.jta.DataSource': XAER_NOTA : The XID is not valid 

             XAER_NOTA說明transaction branch在ResourceManager端(DB, MQ等)不存在。不存在通常由兩種可能:transaction branch被timeout掉了,另外一種情況就是這個(gè)branch壓根就沒有在ResourceManager端發(fā)起過。
            這篇文章主要針對2做一下說明,對于1,我們可以在Weblogic的XAConnectionPool設(shè)定中Enable XA Transaction Timeout, 并對此設(shè)定一個(gè)合理的值,建議這個(gè)值比global transaction timeout大。這樣weblogic在調(diào)用xaStart()的時(shí)候,會通知RM,該branch的timeout時(shí)間,而不是使用RM自己默認(rèn)的timeout(對于Oracle, 默認(rèn)為60秒,但一般會在120秒的時(shí)候,tx branch才會被Oracle timeout掉)。
            
            對于2, 一般會跟配置有關(guān)系,比如兩個(gè)XA datasource指向同一個(gè)XAConnectionPool, 或多個(gè)XAConnectionPool指向同一個(gè)Database,我們以多個(gè)datasource指向同一connection為例:

           1:假如我們有如下的配置環(huán)境:
             XADatasource_11---->XAPool_A---->Databse_A
             XADatasource_21---->XAPool_B---->Databse_B

            這樣的配置環(huán)境中,我們做XA相關(guān)的操作是沒有問題的。

     1         public void xaTest()
     2       {
     3            try{
     4                UserTransaction tx = getUserTransaction();
     5                tx.setTransactionTimeout(1000);
     6                tx.begin();
     7                Connection conn1 = getConnection("t3://localhost:7011", XADatasource_11);
     8                Connection conn2 = getConnection("t3://localhost:7021", XADatasource_21);
     9                this.executeInsertInPSMT(conn1, null);
    10                this.executeAnoInsertInPSMT(conn2, null);
    11                conn1.close();
    12                conn2.close();
    13                tx.commit();
    14            }catch(Exception e){}
    15       }


          2:如果基于業(yè)務(wù)需要,我們需要額外配置兩個(gè)XA Datasource,分別指向 XAPool_A、XAPool_B,如下:
            XADatasource_12----〉XAPool_A
            XADatasource_22----〉XAPool_B
          部署Datasource的時(shí)候,Weblogic會判斷這個(gè)Datasource是不是XA類型 的,如果是XA類型的Datasource,我們需要將這個(gè)datasource實(shí)例注冊到Process- wide的resourceDescriptorList中,如下:
          registerResource(poolName, (XAResource)driverInstance, registrationProperties);
          在register前,我們先調(diào)用unregisterResource(poolName)將該poolName 對應(yīng)的resource從 resourceDescriptorList中unregister掉。這樣 XADatasource_12、XADatasource_22部署后,我們可以看到process-wide的 resourceDescriptorList中的對象變化:
            部署前:XADatasource_11, XADatasource_21
            部署后:XADatasource_12, XADatasource_22
            注意:如果XADatasource11、12, XADatasource_21、22不存在多數(shù)據(jù)源 指向同連接池的話,部署后,四個(gè)Datasource應(yīng)該都出現(xiàn)在 resourceDescriptorList中。

          3:如果我們此時(shí)執(zhí)行xaTest()測試代碼,過程如下:
              3.1:Connection conn1 = getConnection("t3://localhost:7011", XADatasource_11);
                   在getConnection()的時(shí)候, weblogic中需要將 XAResource enlist到當(dāng)前的transaction中,如下:

                   Thread [ExecuteThread: '14' for queue: 'weblogic.kernel.Default'] (Suspended)                       
                   ServerTransactionImpl.enlistResource(XAResource) line: 412                       
                   DataSource.enlist(Transaction) line: 1519                       
                   DataSource.refreshXAConnAndEnlist(XAConnection, JTAConnection, boolean) line: 1459                       
                   DataSource.getConnection() line: 452                       
                   DataSource.connect(String, Properties) line: 410                       
                   RmiDataSource.getConnection() line: 329                       
                   RmiDataSource_WLSkel.invoke(int, InboundRequest, OutboundResponse, Object) line: not available                       
                   ClusterableServerRef(BasicServerRef).invoke(RuntimeMethodDescriptor, InboundRequest, OutboundResponse) line: 492                       
                   ClusterableServerRef(ReplicaAwareServerRef).invoke(RuntimeMethodDescriptor, InboundRequest, OutboundResponse) line: 108                       
                   BasicServerRef$1.run() line: 435                       
                   AuthenticatedSubject.doAs(AbstractSubject, PrivilegedExceptionAction) line: 363                       
                   SecurityManager.runAs(AuthenticatedSubject, AuthenticatedSubject, PrivilegedExceptionAction) line: 147                       
                   ClusterableServerRef(BasicServerRef).handleRequest(InboundRequest) line: 430                       
                   BasicExecuteRequest.execute(ExecuteThread) line: 35                       
                   ExecuteThread.execute(ExecuteRequest) line: 224                       
                   ExecuteThread.run() line: 183 
                        
                   3.1.1: 在enlistResource()中,我們首先檢查 XADatasource_11實(shí)例對應(yīng)的resourceDescriptor在process- wide的 resourceDesriptorList中是否存在(很顯然,它是不存在的,因?yàn)槲覀冊诓渴?XADatasource_12的時(shí)候,它被 unregister掉了)。接下來,我們會檢查 XADatasource_11實(shí)例對應(yīng)的resourceInfo在transaction-wide 的 resourceInfoList中是否存在(因?yàn)檫@個(gè)transaction剛剛開始, resourceInfoList中沒有任何 resource)。因?yàn)閄ADatasource_11實(shí)例對應(yīng)的 resourceInfo在resourceInfoList中不存在,我們需要創(chuàng)建一個(gè) XAServerResourceInfo來和XADatasource_11實(shí)例關(guān)聯(lián)。如下:
                   ri = new XAServerResourceInfo(xar)
                  
                   3.1.2: 在XAServerResourceInfo初始化中,我們會再次檢 查和XADatasource_11實(shí)例對應(yīng)的resourceDescriptor 是否在 resourceDescriptorList中存在(同樣,它依然是不存的)。因?yàn)?resourceDescriptor在 resourceDescriptorList中不存在,我們會從xaResource 獲取xarName , 如下:
                   String xarName = aXar.getClass().getName(); //weblogic.jdbc.jta.DataSource
                   然后根據(jù)xarName 去resourceDescriptorList中繼續(xù)檢 查,是否存在該xarName 對應(yīng)的resourceDesriptor。因?yàn)榇藭r(shí) resourceDescriptorList中對象如下:
                   By instance: XADatasource_12, XADatasource_22
                   By name: XAPool_A, XAPool_B
                  
                   3.1.3: 所以無論是根據(jù)XADatasource_11實(shí)例,還是根據(jù) weblogic.jdbc.jta.DataSource都不能從resourceDescriptorList中找到與其對應(yīng) 的 resourceDescriptor。這是我們會根據(jù)xarName (weblogic.jdbc.jta.DataSource)創(chuàng)建一個(gè) resourceDescriptor,如下:
                    rd = (XAResourceDescriptor) create(xarName, aXar, DYNAMIC);
                  
                   3.1.4: XAResourceDescriptor創(chuàng)建完成后,我們會將該 resourceDescriptor放入 resourceDescriptorList中,此時(shí) resourceDescritporList中對象如下:
                   By instance: XADatasource_12, XADatasource_22,XADatasource_11
                   By name: XAPool_A, XAPool_B,weblogic, jdbc.jta.DataSource
                   這是返回到3.1.2的XAServerResourceInfo初始化 中,我們將該resourceInfo的xaResource設(shè)定為傳入的參數(shù) xar,resourceInfo的 name被設(shè)定為3.1.3中的xarName,即weblogic.jdba.jta.DataSource.

                   3.1.5:回到3.1.1, XAServerResourceInfo實(shí)例創(chuàng)建后, 我們根據(jù)resourceInfo的name,來檢查當(dāng)前tx的resourceInfoList 是否存在對應(yīng) 的resourceInfo,對于一個(gè)剛剛開始的transaction,此時(shí)它的resourceInfoList 是空的。如果同名的 resourceInfo被detect到,我們會將該resourceInfo的 enlistElseWhere置為true(即已被enlist)。因?yàn)槲覀冃聞?chuàng)建的resourceInfo之 前沒有被enlist過,所以我們需要調(diào)用resourceInfo的enlist()來將 XADatasource_11 enlist到當(dāng)前tx中。此時(shí)當(dāng)前transaction的resourceInfoList 對象如下:
                   By instance: XADatasource_11
                   By name: weblogic.jdbc.jta.Datasource
                 
                   3.1.6: 在resourceInfo的enlist中,如果resourceInfo的 enlistElseWhere為true, 將要傳遞給xaStart的flag為TMNOFLAGS, 否則為 TMJOIN。然后獲取調(diào)用
                   Xid bXid = getXIDwithBranch((XidImpl)tx.getXID())
                   獲取事務(wù)分支ID, 最后綜合BRANCH_ID, FLAGS 來通知RESOURCE_MANAGER(DataBase_A)啟動一個(gè)事務(wù)。
                   注意:TMNOFLAGS是通知RESOURCE_MANAGER啟動 一個(gè)新事務(wù)
                         TMJOIN是將當(dāng)前線程和BRANCH_ID 對應(yīng)的事務(wù)關(guān)聯(lián)。

               3.2:Connection conn1 = getConnection("t3://localhost:7011", XADatasource_11);
                   3.1中的動作會被重復(fù),但中間的差別如下:
                   
                   3.2.1:XADatasource_21實(shí)例對應(yīng)resourceDescriptor同樣不會 在resourceDescriptorList中被發(fā)現(xiàn),因?yàn)樗呀?jīng)在register XADatasource_22的 時(shí)候被unregister掉了。XADatasource_21對應(yīng)的resourceInfo不存于當(dāng)前 transaction的resourceInfoList中,resourceInfoList中只有XADatasource_11實(shí) 例對應(yīng)的一個(gè)名叫weblogic.jdbc.jta.DataSource的對象,它在3.1.5中被置入。 同3.1.1,我們這時(shí)候需要根據(jù) XADatasource_21, 創(chuàng)建一個(gè)與其對應(yīng)的 resourceInfo, 如下:
             ri = new XAServerResourceInfo(xar)
                 
                   3.2.2:創(chuàng)建XAServerResourceInfo的時(shí)候,因?yàn)榇藭r(shí) resourceDescriptorList中對象如下(參考 3.1.4):
             By instance: XADatasource_12, XADatasource_22, XADatasource_11
             By name: XAPool_A, XAPool_B,weblogic,jdbc.jta.DataSource
             根據(jù)XADatasource_21我們找不到這個(gè)resourceDescriptor,但 我們能根據(jù)xarName,即weblogic.jdbc.jta.Datasource找到一個(gè) resourceDescriptor。因此我們不會去創(chuàng)建一個(gè)新的 resourceDescriptor,而使 用這個(gè)已存在的resourceDescriptor,并用它的名字作為該resourceInfo的名字, 即新創(chuàng)建的resourceInfo名為:weblogic.jdbc.jta.DataSource。因此3.1.3, 3.1.4步驟不會被執(zhí)行。

                 3.2.5:XAServerResourceInfo被創(chuàng)建后,我們會根據(jù) resouceInfo的名字,即 weblogic.jdbc.jta.DataSource, 檢查當(dāng)前tx的 resourceInfoList中是否存在對應(yīng)的resourceInfo。因?yàn)?.1.5結(jié)束的時(shí)候,我們 已經(jīng)將一個(gè)名為 weblogic.jdbc.jta.DataSource的resourceInfo置入當(dāng)前tx的 resourceInfoList中,所以這里我們能夠找到一個(gè)與 weblogic.jdbc.jta.DataSource對應(yīng)的resourceInfo。因此我們會將這個(gè)新創(chuàng)建的 resourceInfo的enlistElseWhere置為true。
                          
                   3.2.6:因?yàn)閞esourceInfo的enlistElseWhere為true, 所以我們 要傳遞給xaStart的flag為TMJOIN(實(shí)際需要的應(yīng)該是TMNOFALGS),接下來會調(diào)用 start(xid, TMJOIN)來通知RESOURCE_MANAGER(Database_B)將當(dāng)前線程和已有的 transaction branch關(guān)聯(lián)。但Database_B中沒有和該global transaction相對應(yīng)的 transaction branch,所以TMJOIN失敗,即如下的錯(cuò)誤會被拋出,
             java.sql.SQLException: Unexpected exception while enlisting XAConnection java.sql.SQLException: XA error: XAER_NOTA : The XID is not valid start() failed on resource 'weblogic.jdbc.jta.DataSource': XAER_NOTA : The XID is not valid
                 
        這個(gè)問題是weblogic的產(chǎn)品限制,它是WAD(work as design)的,并不是產(chǎn)品bug。在weblogic81sp6中,這種配置會有錯(cuò)誤信息輸出。                     

    posted on 2009-01-12 20:48 走走停停又三年 閱讀(3220) 評論(0)  編輯  收藏 所屬分類: Weblogic
    主站蜘蛛池模板: 亚洲国产亚洲综合在线尤物| 欧美亚洲精品一区二区| 男人的好看免费观看在线视频| 亚洲老熟女五十路老熟女bbw| 亚洲中久无码不卡永久在线观看| 精品亚洲永久免费精品| 国产成人精品日本亚洲18图| 免费国产成人高清视频网站| 免费观看成人久久网免费观看| 亚洲性线免费观看视频成熟| 五月婷婷亚洲综合| www视频免费看| 成人国产网站v片免费观看| 91天堂素人精品系列全集亚洲| 国产男女性潮高清免费网站| 国产成人AV免费观看| 亚洲日产乱码一二三区别| 亚洲乱码中文字幕综合| 成人无遮挡裸免费视频在线观看| 成人片黄网站色大片免费观看cn| 亚洲色一区二区三区四区| 亚洲国产成人精品无码区在线观看 | 亚洲成人一区二区| 免费福利在线播放| www免费黄色网| 亚洲一卡2卡3卡4卡5卡6卡| 亚洲产国偷V产偷V自拍色戒| 日本高清免费aaaaa大片视频| 亚洲视频在线观看免费| 黄色a三级免费看| 亚洲区日韩精品中文字幕| 婷婷亚洲久悠悠色悠在线播放| 又黄又爽无遮挡免费视频| 无人在线观看免费高清视频| 免费一级毛片不卡不收费| 蜜臀AV免费一区二区三区| 久久国产免费直播| 妇女自拍偷自拍亚洲精品| 亚洲伊人久久大香线蕉结合| 久久久久亚洲AV成人无码| 亚洲国产精品尤物yw在线|