EJB3 - Controle de transações

Caros,

estou com uma dúvida em relação a controle de transações com EJB e queria compartilhar com vocês.

Eu tenho o seguinte EJB:

@TransactionManagement(TransactionManagementType.CONTAINER)
public class FazAlgoBean() {

	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public void selecionaContatosEExclui() {
		List lista = dao.getContatosParaDeletar();
			for (Contato contato : Contatos)
				try {
					this.apagaContato(contato);
				} catch (Exception e) {
					//logger
				}
			}
	}

	@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	public void apagaContato(Contato contato) trows Exception {
		dao.apagaSubContatos(contato);
		dao.apagaContato(contato);
	}
}

O que eu preciso é que pra cada chamada ao método apagaContato() seja aberta uma nova transação. Com isso, se eu tiver 10 contatos para serem deletados, e o quinto der problema por exemplo, quero que apenas pra esse seja feito rollback e os demais ocorram normalmente.

O que ocorre é que desse modo acima embora esteja explicito REQUIRES_NEW, não é aberta uma nova transação para cada chamada ao método apagaContato() pois ela está no mesmo bean do método selecionaContatosEExclui(), e quem abriria uma nova transação seria o stub criado pelo container, mas neste caso, como a chamada fica local da classe mesmo, não tem interceptação do stub.

Este é meu cenário. As soluções que eu pensei foram:

  1. Controlar a transação manualmente
    Porem, no livro “Enterprise JavaBeans 3.0” está escrito: “É veementemente recomendável não tentar gerenciar transações explicitamente”. Isso me desencorajou bastante usar essa solução, embora me parecesse bem simples injetar o SessionContext, pegar um UserTransaction e dar um begin/commit.

  2. Criar um outro bean local e colocar o método apagaContato(Contato contato) neste bean, assim, seria necessária uma chamada para outro ejb e aí sim iria passar pelo stub e seria criada uma nova transação. Porem, eu não gostei muito dessa solução pq eu preciso ficar criando beans inúteis, algo do tipo FazAlgo2Bean(é claro que não estou usando estes nomes, alias, todos os nomes do meu exemplo são ficticios)

Queria saber se alguem jah passou por isso e como foi resolvido. Se existe uma terceira solução, ou se uma dessas que eu citei é a mais recomendada.

Obrigado.

PS: O código apresentado é meramente ficticio e não leva em consideração nenhuma boa prática de programação. É apenas para ilustrar o cenário em que me encontro.

Não é a solução mais adequada:
dentro do seu EJB FazAlgoBean, coloque uma interface local desse mesmo bean e chame o método apagaContato dessa interface ao invez de fazer this.apagaContato.

[quote=microfilo]Não é a solução mais adequada:
dentro do seu EJB FazAlgoBean, coloque uma interface local desse mesmo bean e chame o método apagaContato dessa interface ao invez de fazer this.apagaContato.[/quote]

Já haviam me sugerido essa solução, mas eu não achei ela muito elegante, embora seja bem simples e clara. Você usa ela em seus projetos ou você nunca passou por esse problema antes?