我已经实现了数据库日志记录,以将我的 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/