Erro ao fazer commit em banco Oracle. Mensagem estranha

3 respostas
Danilo_Marchiori

Olá,
estou com um problema ao executar um sql em um banco Oracle.
Abaixo segue o trecho de código que tenta apagar um registro do banco. O erro ocorre dentro do finally, quando eu tento fazer o commit. A mensagem de erro é: “Calling commit() on a Connection is not allowed during a global transaction.”

....
		Connection conn = null;
		
		conn = dataSource.getConnection();
		
		conn.setAutoCommit(false);
		
		PreparedStatement prepStmt = null;
		Long codeRecurso = null;
		try
		{
			codeRecurso = pk;
			
			prepStmt = conn.prepareStatement(DELETE_SQL);
			int i=1;
			setLongValue(prepStmt,i++,codeRecurso);
			
			prepStmt.execute();
		}
		catch(SQLException erro)
		{
			
			System.out.println("Erro ao apagar. Messagem: " + erro.getMessage());
			throw erro;
		}
		finally
		{
			// Fechar conexões
			try
			{
				prepStmt.close();
				conn.commit();
				conn.close();
			}
			catch(Exception e)
			{
				System.out.println(e.getMessage());
			}
		}
		....
O lance estranho é que se eu tirar as linhas:

conn.setAutoCommit(false);

conn.commit();

o delete não funciona. E com esse código o delete funciona,  que dispara essa exceção.

O banco é o Oracle 10g.

Alguma idéia galera?

3 Respostas

J

O commit deve ficar logo após o prepStmt.execute(); junto com o prepStmt.close(); e no finally você faz:

if (conn != null) { conn.close(); }

No bloco try/catch principal você coloca no catch:
conn.rollback();
Pra poder voltar as alterações caso dê erro.

Caso dê erro no commit será levantada uma exceção e a conexão será sempre fechada caso ela tenha sido criada.

O bloco finally é sempre executado a não ser que você explicitamente desvie o código com um throw new Exception() por exemplo.

Danilo_Marchiori
Alterei o código fazendo isso que você sugeriu, e ficou assim
Connection conn = null;
		
		conn = dataSource.getConnection();
		
		conn.setAutoCommit(false);
		
		PreparedStatement prepStmt = null;
		Long codeRecurso = null;
		try
		{
			codeRecurso = pk;
			
			prepStmt = conn.prepareStatement(DELETE_SQL);
			int i=1;
			setLongValue(prepStmt,i++,codeRecurso);
			
			prepStmt.executeUpdate();
			conn.commit();
			prepStmt.close();
		}
		catch(SQLException erro)
		{
			System.out.println("Erro ao deletar. Messagem: " + erro.getMessage());
			conn.rollback(); 
			throw erro;
		}
		finally
		{
			if (conn != null)
			{
				conn.close();
			}
		}
Porém o erro ainda continua no conn.commit(). Fazendo testes eu vi q o commit funciona quando eu abro a conexão de maneira diferente:
conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.2:1521:BANCO", "teste", "teste");
Mas desse jeito dá exceção no conn.close().

O que você acha cara?

J

Por que você colocou o throw erro; após o rollback?

Esse seu método já não tem um throws pra propagar a exception?

De qualquer forma coloca aí o stacktrace completo.

Criado 19 de setembro de 2006
Ultima resposta 19 de set. de 2006
Respostas 3
Participantes 2