我有一个Bean管理 MDB -InvoiceInquiryMessageBean ,其中包含以下定义,该定义调用执行数据库操作的 CMT - InvoiceManager 。
MDB明确提到 Bean托管,而onMessage()的事务 NOT_SUPPORTED 。因此,此MDB在没有事务划分的情况下运行。
下面的 InvoiceManager bean 没有定义事务类型或事务属性。所以默认情况下它是一个容器管理的CMT ,并且默认情况下的事务类型为 REQUIRED 。这个bean执行数据库操作。问题是
问题#1
如果在执行数据库操作(如违反主键,数据库死锁,如SQL服务器错误代码1205)时出现任何错误/异常,则数据库事务将被视为失败。此DB事务失败是否会影响调用MDB。
这个问题的原因是我看到有时在数据库异常期间将消息重新传递给MDB。即使MDB被定义为不参与任何容器管理事务,db问题也与数据库事务有关,这将导致将消息重新传递给MDB。
如果我的问题不清楚,请告诉我。
@TransactionManagement(TransactionManagementType.BEAN)
@MessageDriven(name = "NonPersistentInquiryMessageBean", activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") })
public class InvoiceInquiryMessageBean implements MessageListener
{
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public void onMessage(Message msg)
{
call a CMT Bean(CMT_DB_Bean) which performs database operations
}
}
CMT Bean
@Stateless
public class InvoiceManager implements InvoiceManager Local {
entityManager.update();
}
答案 0 :(得分:0)
这个问题的原因是我看到有时在数据库异常期间将消息重新传递给MDB。
我认为您的问题是关于异常处理,而不是关于事务划分。 事实上,MDB和会话bean在不同的事务中执行并不意味着它们与异常传播隔离。
当您的会话bean抛出异常时,它会传播到客户端(在本例中为InvoiceInquiryMessageBean)。如果您的MDB没有处理它,Container将不会确认该消息,因此,它将被重新传递。
一种可能的解决方案是在MDB中处理异常。
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public void onMessage(Message msg)
{
try {
call a CMT Bean(CMT_DB_Bean) which performs database operations
} catch (Exception e) {
//log
}
}