Transações MySQL + EJB

Oá, pessoal
To com um problema. Uso EJB para fazer controle de transações na minha aplicação, sobre banco de dados MySQL 5.

Pois bem … a idéia é fazer vários updates e inserts no mesmo método do EJB, e SÓ comitar se tudo correr bem, ou seja, ao final do processo. Ocorrendo qualquer problema, em circunstâncias normais, o próprio EJB deveria fazer esse controle e rolbecar tudo.
Configurei o EJB pra fazer isso, mas não tá acontecendo …

Meu ejb-jar

      <session >
         <description><![CDATA[Description for Recebimento]]></description>
         <display-name>Name for Recebimento</display-name>
         <ejb-name>Recebimento</ejb-name>
         <home>com.business.session.interfaces.RecebimentoHome</home>
         <remote>com.business.session.interfaces.Recebimento</remote>
         <ejb-class>com.business.session.ejb.RecebimentoSession</ejb-class>
         <session-type>Stateless</session-type>
         <transaction-type>Container</transaction-type>
      </session>

Meu método, que quero executar, no EJB.

	public boolean incluirDocumento(DocumentoVO documentoVO) throws EJBException {
		try {
			PrcRecebimentoDAO prcRecebimentoDAO = new PrcRecebimentoDAO();
			if (prcRecebimentoDAO.insertDocumento(documentoVO)) {
				PrcContabilidadeDAO prcContabilidadeDAO;
				
				Iterator itPlanilhas = documentoVO.getListaPlanilhas().iterator();
				while (itPlanilhas.hasNext()) {
					PlanilhaVO planilhaVO = (PlanilhaVO)itPlanilhas.next();
					prcContabilidadeDAO = new PrcContabilidadeDAO();
					if (!prcContabilidadeDAO.insertPlanilha(planilhaVO)) {		
								throw new EJBException();
						}	
				}
				return true;
			} else {
				return false;
			}
		} catch (DAOException e) {
			e.printStackTrace();
			throw new EJBException();
		}
	}

Como dá pra ver, há dois INSERTS. Um em DOCUMENTO (primeira chamada ao DAO), e outro em PLANILHAS. Acontece, que, ocorrendo erro no INSERT em PLANILHAS, ainda assim o INSERT em DOCUMENTO é comitado, quando não deveria.

Não sei se é problema no EJB, no MySQL, ou no JDBC. Já pesquisei, mas não achei nada que possa me ajudar.

Obrigado.

Opa,

Bem até o EJB 2.1 o rollback acontece apenas nas alterações realizadas no banco de dados que envolve operações no banco com entity beans… as demais você deve controlar. Não tenho certeza, mas acho que vi em algum lugar falando que esta propriedade está disponível na versão 3.0.

Neste caso use a conexão para os dois e coloque o rollback aí no teu método… Sugestão crie uma classe factory de conexão e um construtor passando a connection como parâmetro.

:okok:

Pois é, eu tentei rollbackar na mão, mas ele me deu o seguinte.

14:50:15,500 INFO  [STDOUT] java.sql.SQLException: Can't call rollback when autocommit=true
14:50:15,500 INFO  [STDOUT] 	at com.mysql.jdbc.Connection.rollback(Connection.java:4729)
14:50:15,500 INFO  [STDOUT] 	at org.local.pattern.IBaseDB.rollback(IBaseDB.java:151)
14:50:15,500 INFO  [STDOUT] 	at com.business.session.ejb.Recebimento.incluirDocumento(Recebimento.java:114)

O autocommit do MySQL tá habilitado. Alguém sabe como dsesabilito?

opa, beleza, isto é o seguinte, o problema não está no mysql, e sim na implementação, nem é problema na verdade, é só acrescentar esta instrução (conn representa o objeto connection):

conn.setAutoCommit(false);

ps: Não esqueça de realizar o commit.

:okok: