私はシングルトンダオクラスの接続オブジェクトがメンバー変数で競争条件になりがちなレガシーコードを扱っています。スレッドセーフでないjava.sql.Connectionオブジェクトをjavaで使用する可能性はありますか?
私はこれが潜在的な設計上の問題だと知っていますが、私はjavaのjdbc接続オブジェクトを扱うときに考えられるさまざまなタイプの問題について知りたいと思っています。続き
はEventLoggerDAOクラスのコードです:
package com.code.ref.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import com.code.ref.utils.common.DBUtil;
import com.code.ref.utils.common.PCMLLogger;
public class EventLoggerDAO {
private static EventLoggerDAO staticobj_EventLoggerDAO;
private Connection obj_ClsConnection;
private PreparedStatement obj_ClsPreparedStmt;
private EventLoggerDAO() {
try {
obj_ClsConnection = DBUtil.getConnection();
} catch (Exception e) {
PCMLLogger.logMessage(EventLoggerDAO.class, "EventLoggerDAO()", "Some problem in creating db connection:" + e);
}
}
public static synchronized EventLoggerDAO getInstance() {
if (staticobj_EventLoggerDAO == null) {
synchronized (EventLoggerDAO.class) {
if (staticobj_EventLoggerDAO == null)
staticobj_EventLoggerDAO = new EventLoggerDAO();
}
}
return staticobj_EventLoggerDAO;
}
public void addEvent(String sName, String sType, String sAction, String sModifiedBy) throws Exception {
StringBuffer sbQuery = new StringBuffer();
sbQuery.append("INSERT INTO TM_EVENT_LOG (NAME, TYPE, ACTION, MODIFIED_BY) ").append("VALUES (?, ?, ?, ?) ");
if(obj_ClsConnection == null)
obj_ClsConnection = DBUtil.getConnection();
obj_ClsPreparedStmt = obj_ClsConnection.prepareStatement(sbQuery.toString());
obj_ClsPreparedStmt.setString(1, sName);
obj_ClsPreparedStmt.setString(2, sType);
obj_ClsPreparedStmt.setString(3, sAction);
obj_ClsPreparedStmt.setString(4, sModifiedBy);
obj_ClsPreparedStmt.executeUpdate();
if (obj_ClsPreparedStmt != null) {
obj_ClsPreparedStmt.close();
obj_ClsPreparedStmt = null;
}
}
}
問題はを観察:
時には表に挿入停止しTM_EVENT_LOG
とさえ例外がサーバーログに存在しないことが起こります。
競合状態では、異なるスレッドによって保持されている接続オブジェクトが矛盾した状態になり、データをコミットしていない可能性があります。接続は、接続プールを維持しているwebsphereデータソースによって導出されます。
これはなぜ起こっているのでしょうか?
コードをフォーマットするためのCarlさんに感謝します。私はintiallyしかし無駄にしようとした。 – Tushu
ここで競争条件には明らかで非常に深刻な問題があります。あなたが知っている問題を修正することをお勧めします。 (オッカムのカミソリとそのすべて)。 –
上記のコードで、アプリケーション・サーバーのログに「java.sql.SQLException:ORA-01000:maximum open cursors exceeded」というメッセージが表示されました。私の荒々しい考えでも、このオブジェクトを接続プールに戻さずにこの接続を保持したい場合でも、SQL文を実行した後に毎回接続を閉じることは必須ですか? – Tushu