3

アプリケーションの負荷テストを行っているところ、デッドロック エラーが発生します。このシナリオでは、10 人の異なるユーザーが同時にデータベースを挿入および更新しています。私はオンラインで調べましたが、まだそれを解決する方法を見つけることができませんでした. ここに、デッドロックに関係する私のサンプル コードを添付します。

デッドロックを解決するためのアドバイスをくれる人はいますか? 前もって感謝します。

SampleController:

onSubmit(userAccount)
{
     sampleBO.testDeadLock(userAccount.getUserAccountId());

}

サンプルBO:

public void testInsert(Long id)
{
    sampleDAO.testInsert4(id);      
}

public void testDeadLock(Long id)
{
    testInsert(id);
    sampleDAO.testUpdate4(id);  
}

サンプルDAO:

public void testInsert4(Long id)
{
    StringBuffer sbSql = new StringBuffer();
    sbSql.append(" INSERT INTO Test ");
    sbSql.append(" ( ");
    sbSql.append(" id, ");
    sbSql.append(" note ");
    sbSql.append(" ) ");
    sbSql.append(" VALUES ");
    sbSql.append(" (");
    sbSql.append(""+id+",");
    sbSql.append(" 'test' ");
    sbSql.append(" )");

    //Execute SQL using Spring's JDBC Templates
    this.getSimpleJdbcTemplate().update(sbSql.toString());
}

public void testUpdate4(Long id)
{       
    StringBuffer sbSql = new StringBuffer();
    sbSql.append(" UPDATE Test WITH(ROWLOCK) SET ");
    sbSql.append(" note = 'test1111'");
    sbSql.append(" WHERE id="+id);

    //Execute SQL using Spring's JDBC Templates
    this.getSimpleJdbcTemplate().update(sbSql.toString());
}
4

1 に答える 1

0

デッドロックが発生している場合は、次の場合を除いて、提供したコードからではありません。

  • このテストプログラムの複数のインスタンスが同時に実行されています。
  • 上記のコードは非同期で実行されていましたが、そうではないようです。
  • これらのテストを実行しているときは、データベースに他のアクティビティがあります。

私のお金は最後のものにあります。

SQLトレースを実行し、何がいつ実行されているかを正確に特定することで、これらのデッドロックが発生している理由を見つけることができます。


それぞれ独自のものですが、SQLクエリをこのように宣言できることをご存知ですか?@を使用すると、テキストを複数行に移動したり、円記号などの特殊文字をエスケープしたりできます。

string sbSql = @"
    INSERT INTO Test (id, note)
    VALUES ({0}, 'test')";

sbSql = string.Format(sbSql, id);

WITH(ROWLOCK)おそらくどちらも必要ありません。SQL Serverが関連するロックを実行する時間の99.9%であり、複雑または異常な状況に対してのみ特定のロックを明示的に強制する必要があります。

于 2012-08-19T23:08:22.927 に答える