EJB2.0雨夜教程之六..MDB
MDBMessage-Driven-Bean
消息驱动Bean
我们这次的包里除了MDB还有JMS就是因为MDB是基于JMS的
这就好比我们的EJB是基于RMI一样.
MDB与之前的BMP和CMP都不相同.
1,没有继承任何接口,这就意味着它不能被远程方法直接调用.
2,它仅仅能够接收本地的消息.同时它也仅仅有一个方法就是onMessage().
这也就是之前JMS最后的例子里说的它要实现一个MessageListener.
3,它是无状态的.这样它的多个实例能够处理多条同时传来的消息.
最后注明一下..这东西就是一个class.没了.
下面讲一个上次提到的问题.
毒消息.(poison Message)
话说每次接收端都会通知我们的中间件告知接收到了.这样中间件便不会发送了.
当然如果有了异常出现没有对容器指明异常依然不会发送,但是我们的实际操作是已经异常出现了.
数据的处理会是错误的.
但若标识了异常我们收到了这时容器会一直报异常.
我们的中间件这样便会一直发送.
以次循环不停发.
这个异常比如说.我们根据发送过来的消息创建一条数据.同时修改一个已经存在的.
其中一个完成了另一个没有完成这样就有了异常.这样便不会发送给中间件通知它收到了.
如何解决毒消息?
1,在服务器限制中间件发送的次数.
jms-->service-->选中你的服务..然后再选择你的目的地.Destinations-->无论是选择的是queue还是topic
都只需要在redelivery这个标签里的Redelivery Limit后面的-1改成0这样就仅仅发送一次了.
2,自己管理事务.
首先把bean改成使用驱动Bean管理.而不是使用容器管理.然后我们用事务就ok了.注意抛异常.
当我们用Bean管理的时候要首先支持两阶段事务.
在services-->JDBC--->Data Source在里面选中我们的JNDI.然后点击那个show.
看到下面有个Emulate Two-Phase Commit for non-XA Driver
把前面勾上.这样就可以支持了.别忘记点apply.
!光标开始闪烁..这是提醒我们重新启动weblogic..
写一个简单的MDB步骤.
1,new project
2,new EJBmodule
3,右边空白处右键create messageBean
4,在onMessage里写代码.
注意抛异常.
保存.
make.
deploy.
完成.
特别提醒..我们的MessageBean说白了就是个接收端.一定要记牢. 以下是流程:
在写MDB之前
大家最好先把JMS的文档都看一下..
最重要的是这篇的后半段我后加的.
好下面用JBuilder来..
非常简单.
这些参数都是根据JNDI来的.
不难明白吧.
这里我们写这个是用来接收topic.
看到了吧只有1个java文件.
我们只需要在onMessage里写代码.
这样就写完了.
我们做的就是把接收的信息输出.
部署完成.
我们调用发送者.这个是用上次的TopicRainSendScreen
发现一次发送2次接收..奇怪吧..
因为我之前写了一个.我们把那个删掉.
因为是发布/订阅啊.所以部署的两个等于是两个接收同时做.所以显示在weblogic控制端的就是那样了.
这个简单的例子就这样完成了.
下面我们会写一个小的综合例子.
1,创建一个cmp
2,创建一个sessionBean
3,创建一个mdb
4,给我们的session添加一个方法.perform().
1),在里面调用CMP创建一条记录.然后
2),根据传递过来的id查找一条记录.
注意在catch里面加入throw new EJBException();
这样做是为了让容器知道我们接收端有异常报告.它会回滚所有这个方法的记录.
也就是我们的第一种解决毒消息的方法.
如果没有这个抛出.容器是不会识别出有异常的.可以说这是个有异常的标识.需要我们给容器指出来.
标识出来之后它会一直抛.容器便会一直发.
=========Bean管理的话==============
首先要改为Bean管理.然后我们的方法里写这些.
这里用到了事务.我们实现了MessageDrivenContext,所以便有了getUserTransaction();这个方法返回
UserTransaction对象.我们用它来控制.有了异常我们要数据回滚也是用它..不用抛什么EJBException了.
因为我们现在用Bean处理而不是Container了.
如果不加回滚的话我们发生的数据依然都会存在数据库.
但我们要的就是成功一起成功失败一起失败.因此这是必须的.切记.
UserTransaction ut = null;
try{
TextMessage message = (TextMessage)msg;
String id = message.getText();
System.out.println(id+"------");
ut = messageDrivenContext.getUserTransaction();
ut.begin();
InitialContext ic = new InitialContext();
InforDzqHome home = (InforDzqHome)ic.lookup("InforDzq");
home.create(new BigDecimal(581),"aaa",new BigDecimal(23),"aaa");
InforDzq data = home.findByPrimaryKey(new BigDecimal(id));
data.setName("abcd");
ut.commit();
}catch(Exception e){
e.printStackTrace();
try {
ut.rollback();
}
catch (SystemException ex) {
}
catch (SecurityException ex) {
}
}
=============================================================================
上面这篇和之前的MDB.txt都是需要先看下的.或者说你结合着录像一起看.
ok..直接上来写了.
第一步.我们创建CMP......这个地方写的是JNDI是为了方便我们引用表的时候直接就不用改了.看到了吧.
就是这个地方.之前一直忘记提了..= =
我们把它的属性的ejbCreate()都选true.这样构造的时候就直接创建了.
第二步.创建一个session.我们写一个方法来进行一些操作.
添加一个记录.然后再查找一条.修改下.
方法里的这些上面的文章都有交待
其实这些程序里面有很多地方有问题会出来.我为了节约时间只写对的不写错的.
但错的内容我都在文章里有介绍.希望能够给大家介绍清楚.= =凑合看吧..
第三步.我们写个测试端看看效果.//刚刚是绑定出错.
效果是添加了一条11记录.然后把第三条的记录age改成99.ok看看吧.没有问题.
这个是我们的session来做的.
第四步.我们来用messageBean来.ok..这样我们就做完了..make部署一下.
ok..我们运行试试吧.已经部署好了..我们用发送端来看看发送一个3.是否能够完成.
看到了吧没问题.
如果我们查找或者说继续发送个4.看看吧它会说已经存在11条记录了.一样不变.
这个就是因为我们让容器为我们做了回滚.节约时间我只写对的.错的大家可以自己试试.
第五步.我来给大家演示用Bean来管理事务.带着大家找下这个方法.这样就可以得到UserTransaction的一个对象.
这样我们就完成了.下面再来部署演示下看看是不是一样.执行ok..^_^
= =因为不是在容器控制了所有看不到.我们直接回滚了.如果没有回滚的话.
发送的4.会造成第四条记录的年龄改成99的.
ok..到此为止我们的MDB就大功告成了...希望我讲的大家能够看懂..= = 楼主辛苦了。
页:
[1]