2013-02-03 18 views
1

我試圖調試Glassfish(EJB應用程序)下的Derby死鎖問題。我想在各個點查看鎖表,所以我寫了下面的代碼。問題出在我撥打電話的每一個地方,鎖定表總是回覆爲空。我錯過了什麼?如何使用SYSCS_DIAG.LOCK_TABLE檢查Derby鎖(表總是顯示爲空)?

private void dumpLockTable() 
{ 
    try (Connection connection = dataSource.getConnection()) 
    { 
     PreparedStatement ps = connection.prepareStatement("SELECT * FROM SYSCS_DIAG.LOCK_TABLE"); 
     ResultSet rs = ps.executeQuery(); 
     ResultSetMetaData rsmd = rs.getMetaData(); 
     int columns = rsmd.getColumnCount();    
     StringBuilder sb = new StringBuilder(); 
     sb.append("Lock Table\n"); 
     while(rs.next()) 
     { 
      for (int col = 1; col <= columns; col++) 
      { 
       sb.append(rs.getString(col)); 
       sb.append("\t|"); 
      } 
      sb.append("\n"); 
     } 
     logger.info(sb.toString()); 
    } 

    catch (SQLException sqle) 
    { 
     logger.throwing(LOG_CLASS_NAME, "dumpLockTable", sqle); 
    } 
} 

這是Glassfish 3.1.2.1下的Derby 10.8。我正在通過以下方式獲取數據源:

@Resource(mappedName="jdbc/myderbyjndi") 
private DataSource dataSource; 

所有其他的Derby活動都是通過實體bean和實體管理器實現的。

回答

1

我從Derby郵件列表中得到了一個答案,我想我應該添加完整性。顯然,實體管理器實際上並不是實際上將命令發送出數據庫(我認爲這聽起來很熟悉,但我已經忘記了這一點),所以這將解釋爲什麼鎖表沒有顯示任何鎖。如果我在執行鎖錶轉儲之前添加一個entityManager.flush(),我會得到一個很好的鎖列表。現在我能夠調試導致死鎖的序列。

1

你的代碼對我來說很合適;我不確定它有什麼問題。

但是也許當你運行它時,那時根本沒有任何鎖。在第一屆會議

  1. ,連接到數據庫,並使用LOCK TABLE語句來鎖定:

    你可能會這樣使用「IJ」工具開始診斷過程,以及兩個「IJ」會議一些表

  2. 在第二屆
  3. ,連接到數據庫並運行SELECT * FROM SYSCS_DIAG.LOCK_TABLE

看看你是否能看到那樣的情景中LOCK_TABLE診斷表的內容。一旦可以,您可以使用相同的技術(在運行代碼時人爲地在ij會話中持有鎖)來進一步調試您的子程序代碼。

關於診斷wikidocs中的Derby鎖定行爲有一些很好的建議。

您可能想爲this Derby enhancement request投票。

+0

我給了那一槍。 ij>獨佔模式鎖表app.mytable; 0行插入/更新/刪除 ij> select * from SYSCS_DIAG.LOCK_TABLE; ... 0行插入/更新/刪除 這兩個ij會話都將鎖表顯示爲空。 – Integrator

+0

請注意,derby.log在死鎖異常發生時顯示一些有限的鎖定數據,所以它必須在某個時刻創建鎖定。 – Integrator

+0

確保您未處於AUTOCOMMIT模式,無論是在IJ會話還是在您的應用程序中。在AUTOCOMMIT模式下,通常會進行鎖定,但在每個語句結束時提交事務,釋放鎖定。 –