6

我不是很熟悉,J2EE所以在解释错误时我可能会犯一些错误。请多多包涵。

我正在尝试对我的 java 企业应用程序运行查询,但glassfish抛出以下异常:

[#|2014-12-05T15:31:00.412+0200|WARNING|glassfishv3.0|javax.enterprise.system.core.transaction.com.sun.jts.CosTransactions|_ThreadID=86;_ThreadName=Thread-1;|JTS5031: Exception [java.lang.RuntimeException: org.postgresql.xa.PGXAException: Error preparing transaction] on Resource [prepare] operation.|#]

[#|2014-12-05T15:31:00.413+0200|SEVERE|glassfishv3.0|javax.enterprise.system.core.transaction.com.sun.jts.CosTransactions|_ThreadID=86;_ThreadName=Thread-1;|JTS5031: Exception [org.omg.CORBA.INTERNAL:   vmcid: 0x0  minor code: 0 completed: Maybe] on Resource [rollback] operation.|#]

[#|2014-12-05T15:31:00.439+0200|WARNING|glassfishv3.0|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=86;_ThreadName=Thread-1;|A system exception occurred during an invocation on EJB OFReportTimeoutService method public void com.companyname.appname.service.OFReportTimeoutService.ofTimeout()
javax.ejb.EJBException: Unable to complete container-managed transaction.
    at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:4962)
    at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4716)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1941)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1892)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:198)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:84)
    at com.sun.proxy.$Proxy307.ofTimeout(Unknown Source)
    at com.companyname.appname.service.__EJB31_Generated__OFReportTimeoutService__Intf____Bean__.ofTimeout(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.companyname.appname.servlet.GFv3EJBInvokerJob.execute(GFv3EJBInvokerJob.java:88)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:213)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557)
Caused by: javax.transaction.SystemException: org.omg.CORBA.INTERNAL: JTS5031: Exception [org.omg.CORBA.INTERNAL:   vmcid: 0x0  minor code: 0 completed: Maybe] on Resource [rollback] operation.  vmcid: 0x0  minor code: 0  completed: No
    at com.sun.jts.jta.TransactionManagerImpl.commit(TransactionManagerImpl.java:330)
    at com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate.commitDistributedTransaction(JavaEETransactionManagerJTSDelegate.java:169)
    at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:843)
    at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:4951)
    ... 14 more
|#]

另一个具有相同版本的glassfishpostgresql和 Web 应用程序的系统不会引发任何异常。他们都有相同的domain.xmlpostgresql.conf文件。

我已经max_prepared_transactions100to10000shared_buffersfrom 32MBto改变了,320MB但它没有用。

有任何想法吗?

编辑: ofTimeout添加代码。

@Startup
@Singleton(mappedName="OFReportTimeoutService")
public class OFReportTimeoutService {

    @EJB
    protected QueueManagerService queueManagerService;

    @EJB
    protected AnalyzerService analyzerService;

    @EJB
    protected  ErrorReportJpaController errorReportJpaController;

    @EJB
    protected ReportJpaController reportJpaController;

    protected Boolean isProcessing = Boolean.FALSE;

    private Boolean exceptionPresent = Boolean.FALSE;
    private String errorText = "error";
    private Integer reportId = 0;

    //@Schedule(second="*/10", minute="*", hour="*", persistent=false)
    public void ofTimeout() {
        //System.out.println("STATE : " + "OfReportTimeOutService is running...") ;
        if(exceptionPresent) {
            ErrorReport errorReport = errorReportJpaController.create();
            errorReport.setErrorDate(new Date());
            errorReport.setErrorText(errorText);
            errorReport.setReport(reportJpaController.find(reportId));
            errorReportJpaController.persist(errorReport);
            exceptionPresent =  Boolean.FALSE;
            if (queueManagerService.getLastReport() != null)
                queueManagerService.resetLastReport();
            isProcessing = Boolean.FALSE;
        }

        if (isProcessing)
            return;

        if (queueManagerService.reportQueueSize() > 0)
            isProcessing = Boolean.TRUE;
        else {
            //System.out.println("STATE : " + "queueManagerService.reportQueueSize == 0 !!!") ;
            return;
        }        

        while (queueManagerService.reportQueueSize() > 0)
            try {
                Report report = queueManagerService.pullReport();
                reportId = report.getId();
                if ( reportId != null )
                    System.out.println("STATE : " + "reportId var") ;
                analyzerService.process(report);
            } catch (ReportJPAException rex) {
                Logger.getLogger(OFReportTimeoutService.class.getName()).log(Level.SEVERE, null, rex);
                exceptionPresent = Boolean.TRUE;
                errorText = rex.toString();
                break;
            } catch (RuntimeException rex) {
                Logger.getLogger(OFReportTimeoutService.class.getName()).log(Level.SEVERE, null, rex);
                exceptionPresent = Boolean.TRUE;
                errorText = rex.toString();
                break;
            } catch (Exception ex) {
                Logger.getLogger(OFReportTimeoutService.class.getName()).log(Level.SEVERE, null, ex);
                exceptionPresent = Boolean.TRUE;
                errorText = ex.toString();
                break;
            }

        if(exceptionPresent) {
            return;
        }

        isProcessing = Boolean.FALSE;
        queueManagerService.resetLastReport();


    }

    public Boolean isProcessing() {
        return isProcessing;
    }

    public void setProcessing(Boolean isProcessing) {
        this.isProcessing = isProcessing;
    }

}
4

1 回答 1

1

我已经解决了这个问题。我们bucardo用于复制我们的 postgresql 数据库。这是我的问题的原因。在 postgresql 日志中,我看到了这样的错误日志:

ERROR:  cannot PREPARE a transaction that has executed LISTEN, UNLISTEN or NOTIFY

这篇博文中,已经解释了问题的原因:

问题是 Postgres LISTEN/NOTIFY 系统不能与准备好的事务一起使用。Bucardo 在源表上使用触发器,该触发器发出 NOTIFY 以让 Bucardo 主守护进程知道某些内容已更改并且需要复制。然而,他们的申请只是偶尔发出 PREPARE TRANSACTION 作为其工作的一部分。因此,他们将更新表,这将触发触发器,触发器将发送 NOTIFY。然后应用程序将发出产生上述错误的 PREPARE TRANSACTION。Bucardo 准备应对这种情况。除了使用通知触发器,Bucardo 守护程序可以设置为以设定的时间间隔查找任何更改。为给定同步更改 Bucardo 行为的步骤很简单:

博客文章中的解决方案对我们不起作用。我们可以承受不复制导致错误的数据库。因此,我们使用以下命令删除了复制:

[root@Baskan config]# bucardo deactivate synclrms
Deactivating sync synclrms

[root@Baskan config]# bucardo purge synclrms
Purging name synclrms

[root@Baskan config]# bucardo remove sync synclrms
Removed sync "synclrms"
Note: table triggers (if any) are not automatically removed!

由于触发器不会自动删除,它们应该手动删除:在我们的例子中,有三个触发器。他们的名字是: bucardo_delta, bucardo_kick_synclrms, bucardo_note_trunc_synclrms bucardo_note_trunc_synclrms

要删除触发器,请使用以下命令:

drop TRIGGER trigger_name on table_name;

以防万一 bucardo 放置的表上可能有其他触发器,您可以在 postgresql 中使用以下命令查看表上的所有触发器:

\dS table_name;

完成这些步骤后,系统开始正常工作,没有抛出任何异常。

于 2014-12-18T11:21:00.017 回答