2012-01-13 10 views
3

hibernateがDBへの書き込みを遅らせる可能性があるかどうかは疑問です。私は、MySQL用に構成された休止状態を持っています。シナリオ私は、80%の読み書きと20%の書き込みがサポートされることを願っています。だから私は自分の書き込みを最適化したくない、むしろ少し前に返すよりも、DBが書き込まれるまでクライアントを待ちます。私のテストでは現在100台のクライアントが並行していますが、CPUは時々最大限になります。すぐにDBに書き込んで、データが書き込まれたときにだけ戻るこのフラッシュメソッドが必要です。Hibernate Delayed Write

私のクライアント側では、書き込み要求とその後の読み取り要求を送信しますが、読み取り要求はnullを返すことがあります。私は、休止状態がすぐにDBに書き込まれていないと思われる。

public final ThreadLocal session = new ThreadLocal(); 

public Session currentSession() { 
    Session s = (Session) session.get(); 
    // Open a new Session, if this thread has none yet 
    if (s == null || !s.isOpen()) { 
     s = sessionFactory.openSession(); 
     // Store it in the ThreadLocal variable 
     session.set(s); 
    } 
    return s; 
} 
public synchronized void flush(Object dataStore) throws DidNotSaveRequestSomeRandomError { 
    Transaction txD; 
    Session session; 
    session = currentSession(); 
    txD = session.beginTransaction(); 
    session.save(dataStore); 
    try { 
     txD.commit(); 
    } catch (ConstraintViolationException e) { 
     e.printStackTrace(); 
     throw new DidNotSaveRequestSomeRandomError(dataStore, feedbackManager); 
    } catch (TransactionException e) { 
     log.debug("txD state isActive" + txD.isActive() + " txD is participating" + txD.isParticipating()); 
     log.debug(e); 
    } finally { 
     // session.flush(); 
     txD = null; 
     session.close(); 
    } 
    // mySession.clear(); 
} 

答えて

2

@Siddharth Hibernateは本当に応答を書くの遅れていない、とあなたのコードも同じことを話すしません。私も以前同様の問題に直面していると疑問に思うかもしれませんが、同じことに直面している可能性があります。休止状態への書き込み要求が多数ある場合、多くのスレッドが同じインスタンスを共有しています。 。 また、トランザクション中にMySQLのログを見て、正確に何が間違っていたのかを見て、これをキャッチすることもできます。

+0

デバッグに少し時間がかかりました。 MySQLのログは素晴らしいです。これらは私のデバッグの結果です。もし私が – Siddharth

2

ヒントをお寄せいただきありがとうございます。デバッグするのに少し時間がかかりました。 MySQLのログは素晴らしいです。 これは、私のインサートとMySQLの書き込みでタイムスタンプをチェックするために実行するものです。 mysqlはすべてのDB操作をバイナリログに記録します。これを読むには、mysqlbinlogというツールを使う必要があります。 my.cnfも "http://publib.boulder.ibm.com/infocenter/tpfhelp/current/index.jsp?topic=%2Fcom.ibm.ztpf-ztpfdf.doc_put.cur%2Fgtpm7%2Fm7enablelogs.html"にする必要があります。 "

最新のmysql binログファイルを確認し、これをログの1行目のgrepに実行してタイムスタンプを取得します。 Javaで、Calendar.getInstance()。getTimeInMilli()を呼び出してタイムスタンプと比較します。 sudo mysqlbinlog mysql/mysql-bin.000004 | grep "mystring" -1

私は私の問題をデバッグしました。それは書き込みの遅れの問題でした。だから私はすべての非同期の代わりに同期書き込みを実装した。言い換えれば、このオブジェクトのためにdbがフラッシュされるまで、サーバーコールは返されません。

+1

私はこれをさらにデバッグして、私のmysqlのbinログが "SET TIMESTAMP = 1327039370/*!* /;"に挿入されていることに気付いています。私の読書は "1327039372711"(Javaの新しいCalendar.getInstance()。getTimeInMilli())で起きています。私の書き込みが私の読み出し前に起こっているようだが、読み出しは失敗する。私は休止状態を使用しています "クエリrowResult = session.createSQLQuery(rowQuery).addEntity(table.getClass());" – Siddharth

+0

私は同じ問題に直面しています、休止状態で同期する非同期呼び出しを変更する方法を教えてください –