我希望有人帮助我。我不知道如何使用glassfish服务器4.0处理ejb容器内的消息驱动bean中的事务。我正在尝试创建服务请求/响应。一个jms发送一条消息,mdb消耗它并在发送响应之后。我的交易系统有问题。当我阅读手册java ee manual时,它说请求和响应必须是两个不同事务的一部分。
以下是我所做的代码,但不幸的是它挂了。我不是交易专家所以我问你是否可以帮助我理解如何处理这种情况
public class BookingManagerBean implements BookingManagerBeanInterface
{
@EJB
private UtilBeanInterface utilBean;
@EJB
private ReservationManagerBeanInterface reservationBean;
@Inject
@JMSConnectionFactory("jms/reservationProcessorQueueFactory")
private JMSContext context;
@Resource(mappedName = "jms/bookingProcessorQueueReceiver")
private Queue bookingProcessorQueueReceiver;
private JMSProducer messageProducer = null;
private JMSConsumer messageConsumer = null;
private String id_reservation = null;
private Map<String,Object> map;
@Override
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public String purchase(Route r, UserCredential u, int passengers, int luggages, double price, int points)
{
Reservation reserv = reservationBean.addReservation(r, u, passengers, luggages, (float) price);
try
{
sendMessageToBookingProcessorBean(reserv, points); // invia il messaggio contenente la prenotazione e il numero di punti utilizzati
receiveMessageFromBookingProcessorBean();
}
catch(JMSException jmse)
{
System.err.println("An error occured " + jmse.toString());
return (id_reservation);
}
return id_reservation;
}
private void sendMessageToBookingProcessorBean(Object messageData, int points) throws JMSException
{
messageProducer = context.createProducer();
messageProducer.send(bookingProcessorQueueReceiver,createMessageForBookingProcessorBean(messageData, points));
}
private Message createMessageForBookingProcessorBean(Object messageData, int points) throws JMSException
{
ObjectMessage msg = context.createObjectMessage();
TemporaryQueue tempQueue = context.createTemporaryQueue();
messageConsumer = context.createConsumer(tempQueue);
map = new HashMap<>();
map.put("reservation", (Reservation) messageData);
map.put("used_points", (Integer) points);
msg.setObject((Serializable) map);
msg.setJMSReplyTo(tempQueue); //setta la coda temporanea dove arriverà la risposta
msg.setJMSCorrelationID(utilBean.getRandomString()); //setta l'id
return msg;
}
private void receiveMessageFromBookingProcessorBean() throws JMSException
{
Message msg = messageConsumer.receive(5000); //attendi 10 secondi se c'è un nuovo msg
if(msg instanceof TextMessage)
{
TextMessage response = (TextMessage)msg;
this.id_reservation = response.getText();
}
}
}
@MessageDriven(mappedName = "jms/bookingProcessorQueueReceiver",
activationConfig = {@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class BookingProcessorBean implements MessageListener
{
@EJB
private ReservationManagerBeanInterface reservationManagerBean;
@EJB
private RouteManagerBeanInterface routeManagerBean;
@EJB
private SenderMailBeanInterface senderMailBean;
@EJB
private UserManagerBeanInterface userManagerBean;
@EJB
private GetterFidelityPointsBeanInterface getterFidelityPointsBean;
@PersistenceContext
private EntityManager em;
@Inject
@JMSConnectionFactory("jms/reservationProcessorQueueFactory")
@JMSSessionMode(JMSContext.AUTO_ACKNOWLEDGE)
private JMSContext context;
Reservation reserv = null;
private HashMap<String, Object> map = null;
private int points;
@Override
public void onMessage(Message message)
{
try
{
ObjectMessage om = (ObjectMessage) message;
map = (HashMap<String,Object>) om.getObject();
reserv = (Reservation) map.get("reservation");
points = (Integer) map.get("used_points");
System.out.println("Processing reservation...");
UserCredential user = reserv.getUsername(); //estrae l'utente
user.getReservationsList().add(reserv); //aggiunge la reservation nella lista delle reservation dell'utente
userManagerBean.updateFidelityPoints(user, points); //aggiorna i punti fedeltà qualora l'utente ne abbia fatto uso
userManagerBean.addFidelityPoints(user, getterFidelityPointsBean.getFidelityPointsByRoute(reserv.getRoute())); //assegna i punti fedeltà
routeManagerBean.updateSeatsRoute(reserv); // aggiorna i posti nel volo
reserv.setId(reservationManagerBean.generateIDReservation()); // genera id reservation
storeInDb(reserv, user, reserv.getRoute()); //effettua persistenza
//senderMailBean.sendEmail(reserv);
TemporaryQueue tempQueue = (TemporaryQueue) om.getJMSReplyTo();
sendIdReversationToBookingManagerBean(tempQueue, reserv.getId(), om.getJMSCorrelationID()); //prende la destinazione temporanea ed il messaggio per la risposta
}
// catch(UnsupportedEncodingException uee)
// {
// System.err.println("An error occured during the sending of the confirmation mail to " + reserv.getUsername().getEmail());
// }
// catch(MessagingException me)
// {
// System.err.println("An error occured during the sending of the email to " + reserv.getUsername().getEmail());
// }
catch(JMSException e)
{
System.err.println("An error occured during the processing of the booking " + reserv.getId());
}
}
private void storeInDb(Reservation r, UserCredential u, Route route)
{
em.persist(r);
em.merge(u);
em.merge(route);
}
private Message createMessageForBookingManagerBean(String id_reservation, String id_correlation) throws JMSException
{
TextMessage msg = context.createTextMessage();
msg.setText(id_reservation);
msg.setJMSCorrelationID(id_correlation);
return msg;
}
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
private void sendIdReversationToBookingManagerBean(Destination ReceiverDestination, String id_reservation, String id_correlation) throws JMSException
{
JMSProducer messageProducer = context.createProducer();
messageProducer.send(ReceiverDestination, createMessageForBookingManagerBean(id_reservation, id_correlation));
}
}