2014-12-05 15 views
6

Tôi không thực sự quen thuộc với J2EE vì vậy tôi có thể mắc phải một số lỗi trong khi giải thích lỗi. Xin vui lòng chịu với tôi.glassfish ném org.postgresql.xa.PGXAException

Tôi cố gắng để chạy một truy vấn trên ứng dụng doanh nghiệp java của tôi, nhưng glassfish ném ngoại lệ sau đây:

[#|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 
|#] 

Một hệ thống với các phiên bản tương tự của glassfish, postgresql, và ứng dụng web không ném bất kỳ ngoại lệ. Cả hai đều có cùng các tệp domain.xmlpostgresql.conf.

Tôi đã thay đổi max_prepared_transactions100-10000shared_buffers32MB-320MB nhưng nó đã không làm việc.

Bất kỳ ý tưởng nào?

CHỈNH SỬA:ofTimeout mã được thêm vào.

@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; 
    } 

} 
+0

Bạn có thể thêm mã của phương thức 'ofTimeout()' vào câu hỏi không? – unwichtich

+0

Tôi đã chỉnh sửa bài đăng của mình và thêm mã @unwichtich – Alptugay

+0

Có lý do cụ thể nào bạn cần sử dụng giao dịch XA không? Các giao dịch XA chỉ nên được sử dụng khi bạn phải đồng bộ hóa trạng thái trên nhiều tài nguyên như ghi phải xảy ra với 2 cơ sở dữ liệu HOẶC nhà môi giới JMS. Nếu bạn chỉ muốn đọc từ hàng đợi, hãy đảm bảo rằng autoAck bị tắt và xử lý các ngoại lệ theo cách thủ công. – JVXR

Trả lời

1

Tôi đã giải quyết được sự cố. Chúng tôi đang sử dụng bucardo để nhân rộng cơ sở dữ liệu postgresql của chúng tôi. Đây là nguyên nhân gây ra sự cố của tôi. Trong bản ghi postgresql Tôi thấy một bản ghi lỗi như thế này:

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

Trong this blog post nguyên nhân của vấn đề đã được giải thích:

Vấn đề là rằng Postgres LISTEN/hệ thống THÔNG BÁO không thể được sử dụng với giao dịch đã chuẩn bị. Bucardo sử dụng một kích hoạt trên các bảng nguồn mà phát hành một NOTIFY để cho phép chính Bucardo daemon biết rằng một cái gì đó đã thay đổi và cần phải được nhân rộng. Tuy nhiên, ứng dụng của họ đã phát hành GIAO DỊCH TRƯỚC như một phần không thường xuyên trong công việc của mình. Vì vậy, họ sẽ cập nhật bảng, mà sẽ kích hoạt các kích hoạt, mà sẽ gửi NOTIFY. Sau đó, ứng dụng sẽ phát hành giao dịch PREPARE tạo ra lỗi ở trên. Bucardo được thiết lập để đối phó với tình trạng này; thay vì sử dụng các trình kích hoạt thông báo, có thể đặt trình nền của Bucardo để tìm bất kỳ thay đổi nào trong một khoảng thời gian đã đặt. Các bước để thay đổi hành vi của Bucardo đối với một đồng bộ đã cho chỉ đơn giản là:

Giải pháp trên bài đăng blog không có tác dụng đối với chúng tôi. Chúng tôi có thể không đủ khả năng sao chép cơ sở dữ liệu gây ra lỗi. Vì vậy, chúng tôi loại bỏ các bản sao với các lệnh sau:

[[email protected] config]# bucardo deactivate synclrms 
Deactivating sync synclrms 

[[email protected] config]# bucardo purge synclrms 
Purging name synclrms 

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

Khi trigger không được gỡ bỏ tự động, họ cần được loại bỏ bằng tay: Trong trường hợp của chúng tôi có ba gây nên.Tên của họ là: bucardo_delta, bucardo_kick_synclrms, bucardo_note_trunc_synclrms bucardo_note_trunc_synclrms

Để thả một kích hoạt lệnh sau đây được sử dụng:

drop TRIGGER trigger_name on table_name; 

Chỉ trong trường hợp có thể có trigger khác trên một chiếc bàn đặt bởi bucardo, bạn có thể sử dụng lệnh sau đây trong postgresql để xem tất cả các trigger trên một bảng:

\dS table_name; 

Sau khi các bước này, hệ thống bắt đầu hoạt động bình thường mà không ném bất kỳ trường hợp ngoại lệ.