Транзакция очереди MQ не откатывается в двухфазной транзакции
У меня есть таймер EJB (EJB 2.1), у которого есть транзакция, управляемая компонентом.
Код таймера вызывает бизнес-метод, который обрабатывает 2 ресурса в одной транзакции. Один из них - база данных, а другой - сервер MQ-очереди.
В качестве сервера приложений используется Websphere Application Server 7 (WAS). Чтобы обеспечить согласованность двух ресурсов (базы данных и администратора очередей), мы включили опцию поддержки двухфазного принятия в WAS. Это необходимо для того, чтобы в случае какого-либо исключения во время работы базы данных сообщение, помещенное в очередь, откатывалось вместе с откатом базы данных и наоборот.
Ниже описан поток:
Когда происходит тайм-аут в коде таймера, вызывается startProcess() в DirectProcessor, который является нашим бизнес-методом. Этот метод имеет блок try, внутри которого есть вызов метода createPostXMLMessage() в том же классе. Это, в свою очередь, вызывает другой метод postMessage() в классе PostMsg.
Проблема заключается в том, что когда мы сталкиваемся с каким-либо исключением базы данных в методе createPostXMLMessage(), сообщение, опубликованное ранее, не откатывается, хотя часть базы данных успешно откатывается. Пожалуйста помоги.
В ejb-jar.xml
<session id="Transmit">
<ejb-name>Transmit</ejb-name>
<home>com.TransmitHome</home>
<remote>com.Transmit</remote>
<ejb-class>com.TransmitBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
</session>
public class TransmitBean implements javax.ejb.SessionBean, javax.ejb.TimedObject {
public void ejbTimeout(Timer arg0) {
....
new DIRECTProcessor().startProcess(mySessionCtx);
}
}
public class DIRECTProcessor {
public String startProcess(javax.ejb.SessionContext mySessionCtx) {
....
UserTransaction ut= null;
ut = mySessionCtx.getUserTransaction();
try {
ut.begin();
createPostXMLMessage(interfaceObj, btch_id, dpId, errInd);
ut.commit();
}
catch (Exception e) {
ut.rollback();
ut=null;
}
}
public void createPostXMLMessage(ArrayList<InstrInterface> arr_instrObj, String batchId, String dpId,int errInd) throws Exception {
...
PostMsg pm = new PostMsg();
try {
pm.postMessage( q_name, final_msg.toString());
// database update operations using jdbc
}
catch (Exception e) {
throw e;
}
}
}
public class PostMsg {
public String postMessage(String qName, String message) throws Exception {
QueueConnectionFactory qcf = null;
Queue que = null;
QueueSession qSess = null;
QueueConnection qConn = null;
QueueSender qSender = null;
que = ServiceLocator.getInstance().getQ(qName);
try {
qConn = (QueueConnection) qcf.createQueueConnection(
Constants.QCONN_USER, Constants.QCONN_PSWD);
qSess = qConn.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
qSender = qSess.createSender(que);
TextMessage txt = qSess.createTextMessage();
txt.setJMSDestination(que);
txt.setText(message);
qSender.send(txt);
} catch (Exception e) {
retval = Constants.ERROR;
e.printStackTrace();
throw e;
} finally {
closeQSender(qSender);
closeQSession(qSess);
closeQConn(qConn);
}
return retval;
}
}