1

Glassfish(EJBアプリ)での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 );
    }
}

これは、Glassfish3.1.2.1でのDerby10.8です。私は次のようにデータソースを取得しています:

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

他のすべてのダービーアクティビティは、エンティティBeanとエンティティマネージャを介して行われます。

4

2 に答える 2

2

あなたのコードは私には問題ないように見えます。何が悪いのかわからない。

しかし、おそらくそれを実行すると、その時点でロックが保持されていないだけです。

「ij」ツールと 2 つの「ij」セッションを使用してこれを行うことで、診断プロセスを開始できます。

  1. 最初のセッションで、データベースに接続し、LOCK TABLE ステートメントを使用していくつかのテーブルをロックします。
  2. 2 番目のセッションで、データベースに接続して SELECT * FROM SYSCS_DIAG.LOCK_TABLE を実行します。

そのようなシナリオで LOCK_TABLE 診断テーブルの内容を確認できるかどうかを確認してください。可能になったら、同じ手法 (コードの実行中に ij セッションで人為的にロックを保持する) を使用して、サブルーチン コードをさらにデバッグできます。

Derby のロック動作の診断に関するいくつかの良い提案がwikidocsにあります。

この Derby 拡張要求に投票することをお勧めします。

于 2013-02-03T17:36:12.747 に答える
1

完全を期すために追加する必要があると思われる回答を Derby メーリング リストから受け取りました。どうやら、エンティティ マネージャーは実際にはデータベースからコマンドをすぐに送信していないようです (聞き覚えがあるようですが、忘れていました)。そのため、ロック テーブルにロックが表示されなかった理由が説明されます。ロック テーブル ダンプを行う前に entityManager.flush() を追加すると、ロックの適切なリストが得られます。これで、デッドロックにつながるシーケンスをデバッグできるようになりました。

于 2013-02-06T01:03:35.713 に答える