2012-03-19 541 views
0

我正在嘗試實現兩階段提交的示例jdbc代碼。有2個數據源,兼容DB2和XA。有2個獨立的jdbc連接創建。我正在使用Atomikos作爲TM。使用這些連接,將更新數據源。但是,更新查詢未執行並返回-911錯誤。我無法弄清楚爲什麼會發生死鎖。而且,這兩個連接都是獨立的並且不相關,所以爲什麼會有死鎖/超時?DB2死鎖問題執行XA事務時SQLCODE = -911,SQLERRMC = 68

.... 
    try{ 

     //Get the datasource connection using jndi custom class 

     JndiConn jcon1 = new JndiConn("jdbc/myDatasource1"); 
     JndiConn jcon2 = new JndiConn("jdbc/myDatasource2"); 
     UserTransactionImpl utx = new UserTransactionImpl(); 
     try{ 
      //Begin transaction    
      utx.begin(); 

      //Get the connection from the DB 
      conn1 = jcon1.ds.getConnection(); 
      conn2 = jcon2.ds.getConnection(); 

      //Reading the data from the form 
      int frmAccntNum = Integer.parseInt(req.getParameter("frmAccnt")); 
      int toAccntNum = Integer.parseInt(req.getParameter("toAccnt")); 
      int amt = Integer.parseInt(req.getParameter("amt")); 

      //Create a statement from the Connection 

      try{ 
       String selectQuery = "select AccountNumber, Balance from Accounts where AccountNumber =? with ur"; 
       PreparedStatement stmt = conn1.prepareStatement(selectQuery); 
       stmt.setInt(1,frmAccntNum); 
       ResultSet rs = stmt.executeQuery(); 
       rs.next(); 
       Account frmAccnt = new Account(rs.getInt(1),rs.getInt(2)); 
       int tempBal = frmAccnt.getBalance(); 

       PreparedStatement stmt2 = conn2.prepareStatement(selectQuery); 
       stmt2.setInt(1, toAccntNum); 
       ResultSet rs1 = stmt.executeQuery(); 
       rs1.next(); 
       Account toAccnt = new Account(rs1.getInt(1),rs1.getInt(2)); 
       int tempBal2 = toAccnt.getBalance(); 

       } 
       Operations t1 = new Operations(); 
       if(t1.checkAmt(frmAccnt,amt)){ 
        t1.Withdraw(frmAccnt, amt); 
        t1.Deposit(toAccnt, amt); 
       } 


       String updateQuery = "update Accounts set Balance = ? where AccountNumber= ? with ur"; 
       stmt = conn1.prepareStatement(updateQuery); 
       stmt.setInt(1, frmAccnt.getBalance()); 
       stmt.setInt(2,frmAccnt.getAccountNumber()); 
       stmt.executeUpdate(); 

       stmt2 = conn2.prepareStatement(updateQuery); 
       stmt2.setInt(1, toAccnt.getBalance()); 
       stmt2.setInt(2,toAccnt.getAccountNumber()); 
       stmt2.executeUpdate(); 
       //int r1 = stmt.executeUpdate("update Accounts set Balance = "+frmAccnt.getBalance()+"where AccountNumber="+frmAccnt.getAccountNumber()); 

       stmt.close(); 
       stmt2.close(); 

      }catch(SQLException sq){ 
       System.out.println("Setting Rollback true"); 
       sq.printStackTrace(); 
       rollback = true; 
      } 
     }catch(Exception ex){ 
      ex.printStackTrace(); 
     }finally{ 
      if(!rollback){ 
       try{ 
        utx.commit(); 
       }catch(Exception e){ 
        System.out.println("Commit Exception"); 
        e.printStackTrace(); 
        rollback = true; 
        try { 
         utx.rollback(); 
        } catch (Exception e1) { 
         // TODO Auto-generated catch block 
         e1.printStackTrace(); 
        } 
       } 
      } 
      else{ 
       try { 
        utx.rollback(); 
       } catch (Exception e2) { 
        // TODO Auto-generated catch block 
        e2.printStackTrace(); 
       } 
      } 
      try { 
       conn1.close(); 
       conn2.close(); 
      } catch (SQLException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

     } 
    }catch(NamingException nme){ 
     nme.printStackTrace(); 
    } 
+0

試着在你面前關閉RS(我認爲這是rs.close()),然後打開RS1,並密切RS1發佈更新聲明。這有幫助嗎?聽起來像某些東西沒有關閉。 – transistor1 2012-03-19 18:21:42

+0

我試圖關閉rs和rs1,結果仍然是一個死鎖。 – Andy 2012-03-19 19:02:28

回答

1

這是因爲這一點:

ResultSet rs1 = stmt.executeQuery(); 

你想

ResultSet rs1 = stmt2.executeQuery(); 
+0

ahh ...是的..因此解決了它。天哪錯過了這麼愚蠢的東西:( Thnks! – Andy 2012-03-21 20:32:04