我正在使用Jboss5.1.x EJB3.0
我试图在回滚过程中打开新的Transaction以写入数据库。
我能做的唯一方法 t,是当我将事务包装在一个单独的线程中时,这对我来说似乎不对。 它可能会导致任何问题吗?这样做的意义是什么(用新线程换行), 它假设在没有它的情况下工作不是吗?
代码:
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
private void updateCurrentRetryInDB(final CounterCallData counterCall)
{
Thread t = new Thread()
{
@Override
public void run()
{
try
{
ECMSDao.insertErrorToLog(counterCall.getModemIp(), "Time out");
} catch (SQLException e)
{
System.out.println("SQL Exception:" + e.getMessage());
logger.error(TAG + ".updateCurrentRetryInDB, SQLException Error", e);
}
}
};
t.start();
}
谢谢, 射线。
答案 0 :(得分:2)
我有与你相同的要求,在回滚过程中在数据库中写一些东西。
我所做的是创建一个新的有状态EJB,它具有@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
并调用存储在数据库中的save方法。
我没有创建新线程或任何东西,因为这应该由容器处理。
因此,在您的情况下,我认为ECMSDao
应该是@Stateful
ejb @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
而不是方法updateCurrentRetryInDB()
<强>更新强>
假设你有正常情况存储东西,并发生回滚。 在此示例中,我使用托管事务进行模拟。
public class Foo {
@PersistenceContext EntityManager em;
@Inject BarImpl bar; //can also use @EJB depending on your environment
public void fail() {
try {
//do some thing and throw exception to simulate rollback
throw new RuntimeException("Exception occured, please rollback");
} catch(Exception ex) {
bar.save(ex.getMessage()); // <-- This will store the exception message in a new transaction whilst the other transaction is safely rolledback
throw ex;
}
}
@Scope(SESSION)
@Stateful
@TransactionManagement(TransactionManagementType.CONTAINER) //default
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class BarImpl implements Bar {
@PersistenceContext EntityManager em;
@Destroy @Remove public void destroy(){}
public void save(String msg) {
MyEntity m = new MyEntity();
m.setMessage(msg);
em.persist(m);
}
}
答案 1 :(得分:-1)
没有“回滚的中间”这样的东西,因为事务是原子的,因此它已被回滚或没有回滚。我建议使用jms进行日志记录。 另请注意,根据JSR 220:Enterprise JavaBeansTM,版本3.0:
“企业bean不得尝试管理线程。企业bean不得尝试 启动,停止,暂停或恢复一个线程,或改为“,所以至少你可能会影响可移植性。