2017-08-23 10 views
5

指定した期間ごとに実行するようにスケジュールされたquartz-schedulerジョブを登録したdropwizardフレームワークを使用してアプリケーションを作成しました。このジョブは、SQLクエリをSQL Server DBに対して起動し、ResultSetを反復し、後でキューにプッシュされるPOJOクラスにデータを設定します。石英スケジューラはdropwizardアプリケーションでSQLクエリを実行しません

SQLクエリには、where句の関連テーブルのlast_modified_timeカラムを使用して、デルタ時に変更されたレコードのデータをフェッチする複数のテーブルを結合するUNIONがあります。 DBジャーはのpom.xmlに含ま4.4.0-sqljdbcと石英バージョンである2.2.1

クエリは次のようになりますされています

SELECT 
    u.last_modified_date, 
    u.account_id, 
    u.user_id, 
    ud.is_active 
FROM user u WITH (NOLOCK) 
JOIN user_details ud with (NOLOCK) ON u.account_id = ud.account_id AND u.user_id = ud.user_id 
WHERE u.last_modifed_date > ? AND ud.last_modifed_date <= ? 

UNION 

SELECT 
    u.last_modified_date, 
    u.account_id, 
    u.user_id, 
    ud.is_active 
FROM user u WITH (NOLOCK) 
JOIN user_details ud with (NOLOCK) ON u.account_id = ud.account_id AND u.user_id = ud.user_id 
JOIN user_registration_details urd WITH (NOLOCK) ON urd.account_id = u.account_id AND urd.user_id = u.user_id AND urd.reg_id = ud.reg_id 
WHERE urd.last_modifed_date > ? AND urd.last_modifed_date <= ? 

このクエリは、この

のような簡単な接続の文と結果セットで呼び出されました
final ManagedDataSource datasource configuration.getDatabase().build(environment.metrics(), "sql"); 
// configuration is the configuration class in a drop wizard application and configuration.getDatabase() returns 
// the DataSourceFactory with all credentials like user, password and url set into it 
try (Connection conn = dataSource.getConnection()) { 
     int resultSetType = SQLServerResultSet.TYPE_SS_SERVER_CURSOR_FORWARD_ONLY; 
     int resultSetConcurrency = ResultSet.CONCUR_READ_ONLY; 
     LOGGER.info("Starting execution: "); 
     try (PreparedStatement pstmt = conn.prepareStatement(getQuery(), resultSetType,resultSetConcurrency)) 
     { 
     setQueryParameters(pstmt); 
     try (ResultSet rs = pstmt.executeQuery();) 
     { 
      //process results 
     } 
    } 
    } catch (SQLException | IOException ex) { 
     LOGGER.error(“Error occurred “ + ex); 
} 
LOGGER.info("Completed execution: "); 

「実行開始」のログを印刷してレコードを処理し、「完了した実行」を出力します。しかし、実行中に「実行の開始」と「実行が完了しました」というログが出力されることもありますが、このクエリは実際にはSQL DBに対して起動されません。

デルタ時間に変更したレコードが取得されなかったため、プロファイラはクエリが実際に起動されたかどうかを確認し、このクエリがDBに送信されないことを確認しました。また、log4jdbcライブラリhttp://code.google.com/p/log4jdbc/wiki/FAQを追加してクエリをログに出力しようとしましたが、このクエリのログは出力されませんでした。

+0

[もっと速い回答を得るために、どのような状況で「緊急」や他の類似のフレーズを追加することができますか?](// meta.stackoverflow.com/q/326569) - 要約は、ボランティアに対処する理想的な方法ではなく、おそらく回答を得ることに逆効果があります。これをあなたの質問に追加しないでください。 – halfer

+0

@halfer - これを投稿している間に私はすべてのやりとりを読んでいますが、このセクションを忘れてしまいました。私は次回質問を投稿するときにこれを世話します。 – Aman

+0

前にstackoverflowに多くの投稿をしていないので、これについていくつかの提案や回答を得るために必要な情報を入力する必要がある場合は、誰かが提案することができます。 – Aman

答えて

2

with (NOLOCK)はMySQL構文ではありません。ウィザードの設定を見て、正しいRDBMSエンジンを指定しているかどうかを確認してください。特に、SQL Server構文のように聞こえます。

TRANSACTION ISOLATION LEVELにはREAD UNCOMMITTEDのように設定する必要があります。

+0

私は悪いです、これはSQLサーバーです。私はタグと説明を変更しました。しかし、私はこれがDBにこのクエリの実行を実行/ブロックできないと思います。 – Aman

+0

@Aman:SQL Serverクライアント内で手動でクエリを実行しようとしましたが、問題が発生していないかどうか確認してください。 – halfer

+0

@halfer、はい、SQLサーバーで実行しようとしましたが、クエリに問題はありません。 – Aman

0

このクエリでSQLプロファイラを有効にして、自分のサーバーでフィルタを適用して、クエリが実際にアプリケーションからDBに当たっていないかどうかを確認し、プロファイラがDBに遭遇することはめったにないことを確認しました。だから、マイバティスレベルでキャッシュが起こっているかもしれないと思った。次に、ログを追加し、すべての種類のログを有効にし、ローカルレベルまたは第2レベルキャッシュmybatis configurationにキャッシュが存在するかどうかをチェックすることによってmybatisのデバッグ分析を実行しましたが、それは原因ではありませんでした。 次に、spy jdbcドライバlog4jdbc driverを使用して、すべてのクエリ、パラメータ、およびすべてのdb情報要求をdbレベルでログに記録しました。

私の組織では、異なるホストサーバーに展開されたすべてのアプリケーションのログを表示するために、スパンクアプリケーションを使用しています。 Splunkのログを調べているうちに、同じクエリがログに2回印刷されているのがわかりましたが、深刻なことに気がついたときに、インスタンスから印刷して別のインスタンスから別のサーバーに展開しました。私はそのサーバーにログインし、同じアプリケーションが数か月から更新されていないことを発見しました。同じ環境ではあるが2つの異なるサーバー上で実行されている複数のアプリケーションインスタンスであることが判明し、アプリケーションが複数のホストに展開されていることがわかる方法はありません。

ありがとうございました。すべての助けと賞金は@halferです。

関連する問題