Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在jdbc调用中一次减少提交和插入批量记录?_Java_Oracle_Jdbc - Fatal编程技术网

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

Java 在jdbc调用中一次减少提交和插入批量记录?,java,oracle,jdbc,Java,Oracle,Jdbc,我已经实现了数据库日志记录,以便将java weblogic门户应用程序中的某些细节记录到Oracle DB中。 为此,我使用连接池来获取连接,并使用它对存储过程进行jdbc调用 我有一个静态java方法logService,它获取连接对象并调用SP。 这个logservice方法是从java应用程序中的不同位置调用的,并在参数中传递了相关细节,inturn将这些参数传递给SP调用 因此,对于访问门户的每个用户,大约有10-20个logservice方法调用。 因此,我将进行10-20次SP呼叫

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

我有一个静态java方法logService,它获取连接对象并调用SP。 这个logservice方法是从java应用程序中的不同位置调用的,并在参数中传递了相关细节,inturn将这些参数传递给SP调用

因此,对于访问门户的每个用户,大约有10-20个logservice方法调用。 因此,我将进行10-20次SP呼叫,每次呼叫SP时我都必须提交

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

是的,我已经为我的web应用程序安装了如下过滤器

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 }
 }
}
DBLog.logService(param1, param2); // static method call
在重定向到redirectURL后,我在应用程序的许多地方调用logservice,如下所示:

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 }
 }
}
DBLog.logService(param1, param2); // static method call
此日志服务使用连接池对象准备调用SP。 我只是在下面提供一个简单的示例代码,说明我是如何做的

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{}块中提交事务

过滤法--

因此,在doFilter方法的finally块中提交后,我将最终关闭连接。
我做得对吗?它会工作吗?

考虑对每个请求使用事务。您可以创建在处理请求之前打开数据库事务并在之后提交的。这就可以了。

事务性划分,就像安全性和日志记录一样,可以看作是代码的装饰

假设您有一个接口
BusinessTask
,当前所有数据库操作都在实现该接口:

public interface BusinessTask {
   public void doWork();
}
例如,您有一个
AddSavingsAccountTask
和一个
TransferMoneyTask

现在,您可以以这样的方式实现每个任务,即每个任务都单独提交(或回滚)。但是,如果您想创建一个包含创建帐户和立即转账的任务,那么您将遇到麻烦,因为现在您需要更改交易界限

因此,一种方法是定义TransactionDecorator,您可以在其中放置事务划分

public class TransactionDecorator implements BusinessTask{

    private final BusinessTask task;

    public TransactionDecorator(BusinessTask task){
        this.task = task;
    }

    @Override
    public void doWork() {
        //beging transaction
        task.doWork();
        //commit or rollback
    }
}
然后,您可以简单地用事务划分来装饰现有任务:

final AddSavingsAccount addSavingsAccountTask = new AddSavingsAccount();
final TransferFunds transferFundsTask = new TransferFunds();

BusinessTask transaction = new TransactionDecorator(new BusinessTask(){

    @Override
    public void doWork() {
        addSavingsAccountTask.doWork();
        transferFundsTask.doWork();
    }
});

transaction.doWork(); //all the magic happens here
现在,我只是在这里提出一种模式。这在代码中的实现会因设计和代码的结构而有所不同

进一步参考


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

在过滤器中:

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();
  }
}
在您的logger类中:

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

通常,避免使用静力学。可能会考虑重新考虑日志记录的方法。< /P>将一个过滤器添加到Web应用程序中,它将打开Servlet与打开的事务:公共空隙DoFulter(Servlet请求Req,Servlet RealthRESP){Test{{//OpenCurraseFieldLoop.DoFulter(Req,RESP);}最终{//提交事务}}好的但请建议如何在doFilter中提交。。我在上面的帖子中添加了更多的细节。交易划分似乎不错,但我觉得ahanin建议的解决方案似乎对我的案例很有希望。请建议如何在doFilter finally{}方法中提交。Thanks@aa阅读手册:好的。请检查上面贴在标题下的示例代码,-过滤方法--请告诉我是否合适。谢谢