Transação com EJB

2 respostas
kleins

Galera, bom dia!

Tenho um EJB, Stateless onde faço uma transação e estou com uma dificuldade em relação ao commit.

Por exemplo…

Eu gostaria que ao executar o metodo “executeTask”, fosse dado o commit, mas ele esta acontecendo apenas ao final do loop do metodo anterior “execute”.

Tenho 2 metodos neste EJB como abaixo.

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class TaskFacade extends AbstractFacade<Task> implements TaskFacadeLocal {
  1. onde tenho o loop
public Task execute(Task _task) {
        
        Task task = find(_task.getIdtask());
        
        int error = 0;
        int i = task.getTadone();
        int fatia = 100;
        int percent = task.getTaamount() / fatia;
        int contador = 0;
        int progresso = task.getTaprogress();

        if(task.getTadone()>0){

            BigDecimal bgTadone = new BigDecimal(String.valueOf(task.getTadone()));
            BigDecimal bgTaamount = new BigDecimal(String.valueOf(task.getTaamount()));
            BigDecimal bgProgress = bgTadone.divide(bgTaamount).multiply(new BigDecimal("100"));
            BigDecimal bgProgressRound = bgProgress.setScale(1, RoundingMode.DOWN);
            progresso = bgProgressRound.intValue();
            BigDecimal bgRest = bgTadone.remainder(new BigDecimal(String.valueOf(percent)));
            contador = bgRest.intValue();

        }
        
        //LOOP
        while( i < task.getTaamount() ){
            contador++;
            if( contador == percent && task.getTaamount() > 100 ){
                contador = 0;
                progresso++;
                task.setTaprogress(progresso);
                em.merge(task);
            }

            if(executeTransaction(task) == true){
                try {
                        if(taskControlEJB.ckeckTask(task.getIdtask())){
                        task.setTadone(i);
                        task.setTadatefinish( new Date());
                        task.setTastatus(Short.valueOf(String.valueOf(TaskAux.PAUSED)));
                        task = em.merge(task);
                        return task;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                i++;
            }else{
                error++;
                if(error>10){
                    task.setTastatus(Short.valueOf(String.valueOf(TaskAux.ERRO)));
                    task.setTadone(i);
                    task.setTadatefinish( new Date());
                    task = em.merge(task);
                    return task;
                }
            }
        }//FIM LOOP
        
        task.setTadone(i);
        task.setTadatefinish( new Date());
        task.setTastatus(Short.valueOf(String.valueOf(TaskAux.DONE)));
        task = em.merge(task);
        
        if(task.getTaseed() != null){
            Seed seed = seedEJB.findSeedBySeed( task.getTaseed() );
            if( seed != null ){
                seed.setSeqtdeused(seed.getSeqtdeused() + 1);
                seed.setSecounter(seed.getSecounter() + error);
            }
            seedEJB.updateSeedAmount(seed);
        }

        return task;
    }
  1. onde faço cada insert (aqui imaginava dar commit a cada momento)
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    private boolean executeTransaction(Task task) {
        
        try {
            String serial;
            if(task.getTaseed() == null){
                serial = SerializationFactory.getSerialization("DEFAULT").getSerializedString(task.getTasize());
            }else{
                serial = SerializationFactory.getSerialization("DEFAULT").getSerializedString(task.getTasize(), task.getTaseed());
            }
            int tcode = codeFacade.countCodeBySerial(task.getCompany().getIdcompany(), serial);
            if(tcode == 0){
                Code c = new Code();
                c.setCompany(task.getCompany());
                c.setTask(task);
                c.setCodate( new Date());
                c.setCostatus( Short.valueOf(String.valueOf(CodeAux.ACTIVE)));
                c.setCoserial(serial);
                codeFacade.create(c);

                Unit u = new Unit();
                u.setUncreateddate(new Date());
                u.setCompany(task.getCompany());
                u.setCode(c);
                u.setLine(task.getLine());
                u.setUnstatus(UnitAux.WAITING);
                //TODO Mudar para Storaged = 0
                u.setUnstoraged(Short.valueOf("0"));
                unitFacade.create(u);
                
            }else{
                return false;
            }
            return true;
        } catch (Exception e) {
            System.out.println("Erro no EJB do task - transaction");
            e.printStackTrace();
            context.setRollbackOnly();
            System.out.println(e.getMessage()+" "+e.getLocalizedMessage());
            return false;
        }
    }

O Ambiente neste caso é JPA 2 e Glassfish 3.1

Alguém ja teria passado por isso e pode dar uma dica?

Obrigado!!!

Abs

2 Respostas

WRYEL

Eu jurava que você também esta fazendo o certo :shock: , mas olhando no google tenta isso aqui:

coloca um atributo no seu ejb:

@Resource
private SessionContext sessionContext;

e no seu if:

if (sessionContext.getBusinessObject(TaskFacade.class).executeTransaction(task) == true) {
// ...
}

pra ver no que dá … retirei daqui: http://www.java.net/node/705304

edit: uma segunda tentativa, seria declarar uma referencia do propio EJB dentro dele mesmo e fazer a chamada por lá:

@EJB
private TaskFacade taskFacade;

[]'s

kleins

Opa… boa tarde cara!

Então…

Tentei das duas formas mas o comportamento continua o mesmo…

//if(executeTransaction(task) == true){
            //if (sessionContext.getBusinessObject(TaskFacade.class).executeTransaction(task) == true) {  
            if(taskFacade.executeTransaction(task) == true){

Usando o SessionContext ele lança uma exception

Caused by: java.lang.IllegalStateException: Invalid business interface : class br.xxx.TaskFacade for ejb TaskFacade

edited:
Ai mudei e parou de dar o erro, porém ainda assim só quando acaba o loop que o commit acontece.

TaskFacadeLocal tf =  sessionContext.getBusinessObject(TaskFacadeLocal.class); 
            
            //if(executeTransaction(task) == true){
            //if (sessionContext.getBusinessObject(TaskFacade.class).executeTransaction(task) == true) {  
            //if(taskFacade.executeTransaction(task) == true){
            if (tf.executeTransaction(task) == true) {

Eu entendi o link que vc passou, ele diz que pelo proprio método da classe ele não executa como um EJB, certo?

Eu inclusive, anteriormente ja tentei até colocar isso em outra classe, mas o comportamento foi o mesmo.

Estou “encucado” com isso.

De qualquer forma obrigado.

Um abs

Criado 23 de fevereiro de 2012
Ultima resposta 23 de fev. de 2012
Respostas 2
Participantes 2