java - 在java中使用线程不安全的java.sql.Connection对象有什么可能性?

标签 java database multithreading jdbc database-connection

我正在处理遗留代码,其中单例 dao 类中的连接对象是一个成员变量,并且容易出现竞争条件。

我知道这是一个潜在的设计问题,但是我有兴趣了解在处理 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 数据源派生的。

对于为什么会发生这种情况有什么想法或想法吗?

最佳答案

一切都可能发生在这里。请注意,obj_ClsPreparedStmt 是一个成员变量,而它被用作局部变量 - 这似乎是一个比共享Connection 更严重的问题。

关于java - 在java中使用线程不安全的java.sql.Connection对象有什么可能性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4217872/

相关文章:

c# - 在 ASP.NET 中使用线程是否有任何不明显的危险?

java - 最有效的多线程SQL方式(Java)

java 三元运算符内部 + intellij 评估表达式

java - hsqldb 中的连接池

mysql - 如何使用 WHERE 子句获取整列数据并将其放入另一列中?

sql - 在 DB2 中更改主键序列( 'Default' 到 'Always')

java - 从视频帧中检索时间码

java - logback 加载所有appender

java - 将数组作为参数传递时出错 - Java

c# - 错误 : Excepiton in System. Threading.ThreadAbortException:线程被中止