Начать новую транзакцию в середине отката - PullRequest
0 голосов
/ 26 января 2011

Я использую Jboss5.1.x EJB3.0

Я пытаюсь открыть новую транзакцию в середине отката для записи в базу данных.

единственный способ, которым я могсделать это, когда я обернуть транзакцию в отдельном потоке, что мне не подходит.Это может вызвать проблемы?и какой смысл делать это (перенос с новым потоком), он предполагает работать без него, не так ли?

код:

@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();
}

Спасибо, Рэй.

Ответы [ 2 ]

2 голосов
/ 26 января 2011

У меня были те же требования, что и у вас, я записал что-то в базу данных в середине отката.

Я создал новый EJB с состоянием с @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) и вызвал метод сохранения, которыйхранит в базе данных.

Я не создал новый поток или что-то еще, потому что это должно быть обработано контейнером.

Так что в вашем случае, я думаю, 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);
    }

}
0 голосов
/ 26 января 2011

нет такой вещи, как «середина отката», поскольку транзакция является атомарной, поэтому она либо откатана, либо нет.Я бы предложил JMS для регистрации.Также обратите внимание, что в соответствии с JSR 220: Enterprise JavaBeansTM, версия 3.0:

"Корпоративный компонент не должен пытаться управлять потоками. Корпоративный компонент не должен пытаться запускать, останавливать, приостанавливать или возобновлять поток, иличтобы изменить ", так что, по крайней мере, вы можете повлиять на портативность.

...