首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用消息驱动Bean将消息重传到错误队列

用消息驱动Bean将消息重传到错误队列
EN

Stack Overflow用户
提问于 2015-09-12 14:32:28
回答 2查看 2.5K关注 0票数 1

当发生错误时,我需要向队列返回一条消息。

我正在Weblogic 11G (EJB3.0)、Java1.6、javaee 6.0上使用消息驱动Bean,队列位于Oracle数据库(AQJMS)上

我不想把消息发送到错误队列中。

代码语言:javascript
复制
public void onMessage(Message message) {
        try {
            this.processMenssage(message);
        } catch (ServiceInternalException e) {
            // I need return the message to the queue because something wrong (anything) happend
        }
}

我知道信息会被一次又一次地恢复,直到我解决问题为止。

MDB配置了注释。

代码语言:javascript
复制
@MessageDriven(
    name = "MyBeanMDB",
    activationConfig = {
            @ActivationConfigProperty(propertyName  = "destinationType", 
                    propertyValue = "javax.jms.Queue"),

            @ActivationConfigProperty(propertyName  = "connectionFactoryJndiName",
            propertyValue = "AqJms3FSCF"), // External JNDI Name

            @ActivationConfigProperty(propertyName  = "destinationJndiName",
            propertyValue = "myque/REQ_JMSQ") // Ext. JNDI Name
    }
    )
public class MyBeanMDB implements MessageListener{....

因为我的驱动程序数据源是oracle.jdbc.xa.client.OracleXADataSource,所以我有一个weblogic-ejb-jar.xml文件

代码语言:javascript
复制
<?xml version = '1.0' encoding = 'windows-1252'?>
<weblogic-ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-ejb-jar http://www.bea.com/ns/weblogic/weblogic-ejb-jar/1.0/weblogic-ejb-jar.xsd"
xmlns="http://www.bea.com/ns/weblogic/weblogic-ejb-jar">
<weblogic-enterprise-bean>
    <ejb-name>MyBeanMDB</ejb-name>
    <message-driven-descriptor>
        <pool>
            <max-beans-in-free-pool>1</max-beans-in-free-pool>
            <initial-beans-in-free-pool>1</initial-beans-in-free-pool>
        </pool>
    </message-driven-descriptor>
</weblogic-enterprise-bean>

我尝试过使用setRollbackOnly()

添加

代码语言:javascript
复制
 @TransactionManagement(value=TransactionManagementType.CONTAINER)
 @TransactionAttribute(TransactionAttributeType.REQUIRED)

代码语言:javascript
复制
@Override
public void setMessageDrivenContext(MessageDrivenContext ctx) throws EJBException {
    this.myctx = ctx;
}

以及内部异常

代码语言:javascript
复制
public void onMessage(Message message) {
        try {
            this.processMenssage(message);
        } catch (ServiceInternalException e) {
            this.myctx.setRollbackOnly(); // the message is not redelivered
        }
}

RollbackOnly被开具发票,日志上写着:

代码语言:javascript
复制
####<Sep 13, 2015 11:40:33 AM ART> <Info> <EJB> <el01cl03> <AdminServer> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <> <39d906d31eb822f1:-27a94574:14fc3fbcefe:-8000-0000000000000b8a> <1442155233307> <BEA-010213> <Message-Driven EJB: MyBeanMDB's transaction was rolled back. The transaction details are: Name=NewJMSMessagePoller.MyBeanMDB,Xid=BEA1-2BC2680CDDBA895EF953(294629023),Status=Rolled back. [Reason=weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly called on transaction],numRepliesOwedMe=0,numRepliesOwedOthers=0,seconds since begin=0,seconds left=60,XAServerResourceInfo[aqjmsuserDS_e2eSOADomain]=(ServerResourceInfo[aqjmsuserDS_e2eSOADomain]=(state=rolledback,assigned=AdminServer),xar=aqjmsuserDS,re-Registered = false),SCInfo[e2eSOADomain+AdminServer]=(state=rolledback),properties=({weblogic.transaction.name=NewJMSMessagePoller.MyBeanMDB}),local properties=({weblogic.jdbc.jta.aqjmsuserDS=[ No XAConnection is attached to this TxInfo ]}),OwnerTransactionManager=ServerTM[ServerCoordinatorDescriptor=(CoordinatorURL=AdminServer+10.10.10.150:7001+e2eSOADomain+t3+, XAResources={eis/tibjms/Queue, NIICommonDS-rac0_e2eSOADomain, eis/activemq/Queue, 10gDataSource_e2eSOADomain, eis/fioranomq/Topic, eis/jbossmq/Queue, eis/Apps/Apps, eis/aqjms/Topic, eis/webspheremq/Queue, eis/AQ/aqSample, eis/tibjms/Topic, eis/aqjms/Queue, eis/aqjms/colasjmsuser3, ITM_e2eSOADomain, eis/sunmq/Queue, WSATGatewayRM_AdminServer_e2eSOADomain, NIICommonDS_e2eSOADomain, eis/jms/ReprocessJMSQueue, eis/tibjmsDirect/Queue, eis/wls/Queue, aqjmsuserDS_e2eSOADomain, eis/tibjmsDirect/Topic, eis/wls/Topic, eis/pramati/Queue, NIICommonDS-rac1_e2eSOADomain, eis/jms/ReprocessJMS11gQueueCF},NonXAResources={})],CoordinatorURL=AdminServer+10.10.10.150:7001+e2eSOADomain+t3+).>

但是队列中的状态(AQJMS)之后是3(已处理)

也许问题是:

代码语言:javascript
复制
 aqjmsuserDS=[ No XAConnection is attached to this TxInfo ]
EN

回答 2

Stack Overflow用户

发布于 2015-10-25 15:29:01

问题是队列的创建,队列是这样创建的

代码语言:javascript
复制
BEGIN DBMS_AQADM.CREATE_QUEUE_TABLE(
 Queue_table        => '"JMSUSER"."SALES_JMSQTAB"',
 Queue_payload_type => 'SYS.AQ$_JMS_MESSAGE',
 storage_clause     => 'PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 TABLESPACE USERS',
 Sort_list          => 'PRIORITY,ENQ_TIME',
 Compatible         => '8.1.3');
END;

BEGIN DBMS_AQADM.CREATE_QUEUE(
 Queue_name          => 'JMSUSER.SALES',
 Queue_table         => 'JMSUSER.SALES_JMSQTAB',
 Queue_type          =>  0,
 Max_retries         =>  0,
 Retry_delay         =>  0,
 Retention_time      =>  86400,
 dependency_tracking =>  FALSE);
END;

这方面的问题是字段MAX_RETRIES,当为0时,不进行重试(回滚)。

创建队列的更好方法是:

代码语言:javascript
复制
BEGIN DBMS_AQADM.CREATE_QUEUE_TABLE(
 Queue_table        => 'JMSUSER.SALES_JMSQTAB',
 Queue_payload_type => 'SYS.AQ$_JMS_MESSAGE',
 storage_clause     => 'PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 TABLESPACE USERS',
 Sort_list          => 'PRIORITY,ENQ_TIME',
 Compatible         => '8.1.3');
END;

BEGIN DBMS_AQADM.CREATE_QUEUE(
 Queue_name          => 'JMSUSER.SALES_JMSQTAB',
 Queue_table         => 'JMSUSER.SALES_QTAB',
 Queue_type          =>  0,
 Max_retries         =>  2147483647,
 Retry_delay         =>  5,
 Retention_time      =>  259200,
 dependency_tracking =>  FALSE);
END;
票数 2
EN

Stack Overflow用户

发布于 2015-09-12 18:40:49

您能检查下面的代码帮助,它也处理java.lang.Exception,捕捉非ServiceInternalExceptions。还添加一个记录器,以实际发现此异常已被捕获:

代码语言:javascript
复制
    public void onMessage(Message message) {
     try {
        this.processMenssage(message);
     } catch (ServiceInternalException e) {
        Logger.error(e);
        this.myctx.setRollbackOnly(); 
     } catch (Exception e) {
        Logger.error(e);
        this.myctx.setRollbackOnly();
     }
  }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32539962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档