Java OpenCSV+;JMS/MDB行为&x2B;性能问题

Java OpenCSV+;JMS/MDB行为&x2B;性能问题,java,glassfish,jms,message-driven-bean,opencsv,Java,Glassfish,Jms,Message Driven Bean,Opencsv,我有一个在Glassfish 4.1下运行的web应用程序,它包含两个需要JMS/MDB的特性。 尤其是在使用JMS/MDB生成报告方面,我遇到了一些问题,即从表中获取数据并将其转储到文件中 这就是发生的情况,我有一个JMS/MDB消息,它在Oracle数据库中执行两个任务,在表中得到最终结果后,我希望从该表中获得一个csv报告(通常是30M+记录) 因此,在JMS/MDB中,生成报告时会发生以下情况: public boolean handleReportContent() { Co

我有一个在Glassfish 4.1下运行的web应用程序,它包含两个需要JMS/MDB的特性。 尤其是在使用JMS/MDB生成报告方面,我遇到了一些问题,即从表中获取数据并将其转储到文件中

这就是发生的情况,我有一个JMS/MDB消息,它在Oracle数据库中执行两个任务,在表中得到最终结果后,我希望从该表中获得一个csv报告(通常是30M+记录)

因此,在JMS/MDB中,生成报告时会发生以下情况:

public boolean handleReportContent() {

    Connection conn = null;

    try {
        System.out.println("Handling report content... " + new Date());
        conn = DriverManager.getConnection(data.getUrl(), data.getUsername(), data.getPassword());
        int reportLine = 1;
        String sql = "SELECT FIELD_NAME, VALUE_A, VALUE_B, DIFFERENCE FROM " + data.getDbTableName() + " WHERE SET_PK IN ( SELECT DISTINCT SET_PK FROM " + data.getDbTableName() + " WHERE IS_VALID=? )";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setBoolean(1, false);
        ResultSet rs = ps.executeQuery();

        List<ReportLine> lst = new ArrayList<>();
        int columns = data.getLstFormats().size();
        int size = 0;
        int linesDone = 0;

        while (rs.next()) {

            ReportLine rl = new ReportLine(reportLine, rs.getString("FIELD_NAME"), rs.getString("VALUE_A"), rs.getString("VALUE_B"), rs.getString("DIFFERENCE"));
            lst.add(rl);
            linesDone = columns * (reportLine - 1);
            size++;
            if ((size - linesDone) == columns) {
                reportLine++;

                if (lst.size() > 4000) {
                    appendReportContentNew(lst);
                    lst.clear();
                }
            }
        }

        if (lst.size() > 0) {
            appendReportContentNew(lst);
            lst.clear();
        }

        ps.close();
        conn.close();
        return true;
    } catch (Exception e) {
        System.out.println("exception handling report content new: " + e.toString());
        return false;
    }
因此,我正在从结果集中收集所有数据,并转储到CSVWriter。此操作对于相同的20分钟,只写入了7k行

但是同样的方法,如果我在JMS/MDB
之外使用它,它有一个难以置信的不同,就在开始的4分钟内,它在文件中写了3百万行。 在同样的20分钟内,它生成了一个500Mb+的文件

显然,如果我想提高性能,使用OpenCSV是目前为止最好的选择,我的问题是为什么它在JMS/MDB中的性能不一样? 如果不可能,是否有任何可能的解决方案以任何其他方式改进同一任务

我感谢您在这方面提供的反馈和帮助,我正在努力理解JMS/MDB内外的行为/性能不同的原因

**

编辑: **


因此,如果在
generator中执行相同的方法,
handleReportContent()
,deployGenerator()。如果我等待该方法中的所有内容,并使这个bean中的文件
JobProcessorBean
更快。我只是想弄清楚这个行为为什么会这样执行。

在bean上添加
@TransactionAttribute(不受支持)
注释可能会解决这个问题(正如您的评论所指出的那样)


为什么会这样?因为如果不在消息驱动bean上放置任何事务性注释,默认值将变成
@TransactionAttribute(必需)
(因此bean所做的一切都由事务管理器监督)。显然,这会减慢速度。

消息驱动bean上的
@TransactionAttribute
注释是什么?如何在MDB之外调用您的
HandlerReportContentV2
方法?@MaDa我有一个类
JobProcessorBean
,它有以下注释:
@MessageDriven(activationConfig={@ActivationConfigProperty(propertyName=“destinationType”,propertyValue=“javax.jms.Queue”),@ActivationConfigProperty(propertyName=“destinationLookup”,propertyValue=“MessageQueue”)}
此bean注入另一个bean,我在其中调用
deploy()
方法
在部署的bean中使用,我有这些结果。如果复制相同的方法并在不同的bean中运行,我会得到不同的结果。我将添加这部分代码。尝试添加
@TransactionAttribute(不受支持)
,查看这是否对性能有影响。另外,请查看将文件直接保存到web应用程序文件夹中的其他问题。@MaDa会的,我会告诉您是否有任何不同。@MaDa解决了这个问题,它在MDB中执行相同的操作。可以用您以前的示例回答这个问题。@t、 所以我可以接受。谢谢你的时间和帮助。:)
public void appendReportContentNew(List<ReportLine> lst) {

File f = new File(data.getJobFilenamePath());

try {
    if (!f.exists()) {
        f.createNewFile();
    }

    FileWriter fw = new FileWriter(data.getJobFilenamePath(), true);
    BufferedWriter bw = new BufferedWriter(fw);

    for (ReportLine rl : lst) {
        String rID = "R" + rl.getLine();
        String fieldName = rl.getFieldName();
        String rline = rID + "," + fieldName + "," + rl.getValue1() + "," + rl.getValue2() + "," + rl.getDifference();
        bw.append(rline);
        bw.append("\n");
    }

    bw.close();

} catch (IOException e) {
    System.out.println("exception appending report content: " + e.toString());
}
public boolean handleReportContentv2() {

    Connection conn = null;

    try {
        FileWriter fw = new FileWriter(data.getJobFilenamePath(), true);
        System.out.println("Handling report content v2... " + new Date());
        conn = DriverManager.getConnection(data.getUrl(), data.getUsername(), data.getPassword());
        String sql = "SELECT NLINE, FIELD_NAME, VALUE_A, VALUE_B, DIFFERENCE FROM " + data.getDbTableName() + " WHERE SET_PK IN ( SELECT DISTINCT SET_PK FROM " + data.getDbTableName() + " WHERE IS_VALID=? )";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setBoolean(1, false);
        ps.setFetchSize(500);
        ResultSet rs = ps.executeQuery();

        BufferedWriter out = new BufferedWriter(fw);
        CSVWriter writer = new CSVWriter(out, ',', CSVWriter.NO_QUOTE_CHARACTER);
        writer.writeAll(rs, false);

        fw.close();
        writer.close();
        rs.close();
        ps.close();
        conn.close();
        return true;
    } catch (Exception e) {
        System.out.println("exception handling report content v2: " + e.toString());
        return false;
    }
}
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "MessageQueue")})

public class JobProcessorBean implements MessageListener {

private static final int TYPE_A_ID = 0;
private static final int TYPE_B_ID = 1;

@Inject
JobDao jobsDao;

@Inject
private AsyncReport generator;

public JobProcessorBean() {
}

@Override
public void onMessage(Message message) {
    int jobId = -1;
    ObjectMessage msg = (ObjectMessage) message;
    try {
        boolean valid = true;
        JobWrapper jobw = (JobWrapper) msg.getObject();
        jobId = jobw.getJob().getJobId().intValue();

        switch (jobw.getJob().getJobTypeId().getJobTypeId().intValue()) {
            case TYPE_A_ID:
                jobsDao.updateJobStatus(jobId, 0);
                valid = processTask1(jobw);
                if(valid) {
                    jobsDao.updateJobFileName(jobId, generator.getData().getJobFilename());
                    System.out.println(":: :: JOBW FileName :: "+generator.getData().getJobFilename());
                    jobsDao.updateJobStatus(jobId, 0);
                }
                else {
                    System.out.println("error...");
                    jobsDao.updateJobStatus(jobId, 1);
                }
                **boolean validfile = handleReportContentv2();**
                if(!validfile) {
                    System.out.println("error file...");
                    jobsDao.updateJobStatus(jobId, 1);
                }
                break;
            case TYPE_B_ID:
                (...)
        }
        if(valid) {        
            jobsDao.updateJobStatus(jobw.getJob().getJobId().intValue(), 2); //updated to complete
        }
        System.out.println("***********---------Finished JOB " + jobId + "-----------****************");
        System.out.println();
        jobw = null;
    } catch (JMSException ex) {
        Logger.getLogger(JobProcessorBean.class.getName()).log(Level.SEVERE, null, ex);
        jobsDao.updateJobStatus(jobId, 1);
    } catch (Exception ex) {
        Logger.getLogger(JobProcessorBean.class.getName()).log(Level.SEVERE, null, ex);
        jobsDao.updateJobStatus(jobId, 1);
    } finally {
        msg = null;
    }
}

private boolean processTask1(JobWrapper jobw) throws Exception {

    boolean valid = true;
    jobsDao.updateJobStatus(jobw.getJob().getJobId().intValue(), 0);

    generator.setData(jobw.getData());
    valid = generator.deployGenerator();
    if(!valid) return false;
    jobsDao.updateJobParameters(jobw.getJob().getJobId().intValue(),new ReportContent());

    Logger.getLogger(JobProcessorBean.class.getName()).log(Level.INFO, null, "Job Finished");
    return true;
}