java - 在 jdbc 调用中一次减少提交和插入批量记录?

标签 java oracle jdbc

我已经实现了数据库日志记录,以将我的 java weblogic 门户应用程序中的某些详细信息记录到 Oracle 数据库中。 为此,我使用连接池获取连接并使用它对存储过程进行 jdbc 调用。

我有一个静态 java 方法 logService,它获取连接对象并调用 SP。 从我的 Java 应用程序中的不同位置调用此日志服务方法,并在参数中传递相关详细信息,这些参数又传递给 SP 调用。

因此,每个访问门户的用户将调用大约 10-20 次日志服务方法。 因此,我将进行 10-20 次 SP 调用,每次调用 SP 时我都必须提交。

但问题是,我的 DBA 建议不要为每个事务提交,而是一次提交所有 10-20 个事务,因为他说提交频率很高。 我该如何做到这一点?如果不清楚,我可以发布示例代码。

是的,我已经为我的网络应用程序安装了过滤器,如下所示,

public final class RequestFilter implements Filter{

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) {
 try {
      ((HttpServletResponse) response).sendRedirect(redirectUrl);

  if (chain != null) {
            chain.doFilter(request, response);
        }
     }
 finally { // commit transaction here }
 }
}

重定向到 redirectURL 后,我在我的应用程序中的许多地方调用 logservice,如下所示,

DBLog.logService(param1, param2); // static method call

此日志服务使用连接池对象对 SP 进行 prepareCall。 我只是在下面提供了一个简短的示例代码,说明我是如何做的。

public static void logService(String param1, String param2) {

try {

con=getConnection();
stmt = con.prepareCall("{call DB_LOG_SP (?, ?}");
stmt.setString(1, param1);
stmt.setString(2, param2);
stmt.execute();
stmt.close();
}finally {
           stmt.close();
           con.close();
        } 
 }

但由于我在 SP 调用后关闭连接,我如何在 doFilter 方法内的 finally {} block 中提交我的事务?

过滤方法--

public class DBLog {

static Connection con = null;
    static PreparedStatement stmt = null;

static {
        try{
        new net.verizon.whatsnext.dblog.JDCConnectionDriver("oracle.jdbc.driver.OracleDriver", 
        "jdbc:oracle:thin:@localhost:7001:xe","user", "password"); 
    con=getConnection(); // Getting connection from Connection pool

    }catch(Exception e){}
    }

 public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection("jdbc:jdc:jdcpool"); 
    }


public static void logService(String param1, String param2) {
    ...
    finally {
               stmt.close();
            } 
     }

 public static void closeTrans() {

    con.commit();
    con.close();
    }
} //End of DBLog class


 public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) {
    ...
     finally { 
          DBLog.closeTrans();
         }
    }

所以,在 doFilter 方法的 finally block 中提交后,我最终关闭了连接。 我做得对吗?会成功吗?

最佳答案

首先,不要在每个请求上打开连接,而是重用连接池中的连接(可能是 DataSource ),并放入共享空间 - 在您的情况下,最简单的方法是利用静态 ThreadLocal字段。

在过滤器中:

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) {
  Connection conn = obtainConnection(); // obtain connection and store it ThreadLocal
  conn.setAutoCommit(false);
  try {
    chain.doFilter(request, response);
  } finally {
    conn.commit();
  }
}

在您的记录器类中:

public static void logService(String param1, String param2) {
  Connection conn = getConnection(); // obtain thread-local connection
  // your database statements go here
}

一般来说,避免使用静力学。或许可以考虑重新考虑您的日志记录方法。

关于java - 在 jdbc 调用中一次减少提交和插入批量记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10024997/

相关文章:

java - 如何使用 JasperReports 从 Oracle 中的 blob 列查看图像?

java - JDBC - 从 JAVA 调用 PLSQL 会出现 Java.sql.SQLException : ORA-06550

java - Eclipse Java 启动错误 : Selection does not contain a main type

java - WebServiceTemplate 发送原始 XML 作为内容

java - 将匿名函数传递给方法,存储它并执行它?

java - 创建一个java程序来提取svn日志并将它们存储在xml中

java - 使用 TLS 证书的 JDBC 连接到 Oracle 数据库

sql - 在 oracle 中处理 NULL 和 0 的日期格式

java - 加载 Postgresql JDBC 4.1 驱动程序

mysql - 带有 mysql 数据库的 servlet 返回 null