O problema principal de uma Autonomous Transaction fazendo DMLs logicamente relacionados á transação principal é, como eu disse, que com ela vc corre o risco Sério de quebrar a integridade com um eventual ROLLBACK na transação principal de dados , yep ? http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:2212445691154 e http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:469621337269 reforçam e dão outros casos do cenário.... Mais por isso que eu contra-recomendei a A.T. para o outro colega - imho simplesmente Não Vale o risco se qquer Outra opção tecnicamente viável estiver disponível... Eu só aceitaria a A.T. se : - Realmente, Positivamente, Totalmente as outras opções TRANSACIONAIS (como DBMS_JOB, views materializadas em tempo de commit, API que faz os DMLs todos de modo centralizado, etc, etc) foram tentadas / consideradas e - a pessoa TEm consciência dos Grandes Riscos envolvidos, e sabe como programar para os circundar/evitar []s Chiappa
--- Em oracle_br@yahoogrupos.com.br, Alessandro Lúcio Cordeiro da Silva <alecordeirosilva@...> escreveu > > Olá Chiappa, > > Apenas colocando um informação sobre o Autonomous Transaction, eu já usei > este recurso, sem ser para criar LOG, foi a solução ideal para evitar lock no > banco. > > Basicamente era assim, existia uma tabela de Carteira de Cobrança, que tinha > os dados bancarios para geração do boleto, e um campo que continha o valor > atual do campo nosso numero (numero sequencial). Então, se por exemplo, o > financeira começasse a gerar uns 10 mil boletos na carteira do itau, ninguem > mais conseguiria gerar outros boletos enquanto os 10 mil boletos não > terminasse. > > A solução foi criar uma procedure com Autonomous Transaction que somente dava > o update incremental no campo nosso numero e com parametro de saida com o > valor obtido. Então poderia o financeiro gerar o boleto numero 95, depois > outro setor gerar o boleto 96 e o financeiro gerar os 97,9899.... O > comportamento ficou exatamente igual ao uso de uma sequencia. > > > Alessandro Lúcio Cordeiro da Silva > Analista de Sistema > þ http://alecordeirosilva.blogspot.com/ > > > > > ________________________________ > De: J. Laurindo Chiappa <jlchiappa@...> > Para: oracle_br@yahoogrupos.com.br > Enviadas: Terça-feira, 27 de Agosto de 2013 15:53 > Assunto: [oracle_br] Re: ORA-06159 > > > > > Ah, sim, com o código de erro ** CORRETO ** aí sim dá pra entender :^) ... > Consultando a documentação online (comando oerr) temos que : > > 06519, 00000, "active autonomous transaction detected and rolled back" > // *Cause: Before returning from an autonomous PL/SQL block, all autonomous > // transactions started within the block must be completed (either > // committed or rolled back). If not, the active autonomous > // transaction is implicitly rolled back and this error is raised. > // *Action: Ensure that before returning from an autonomous PL/SQL block, > // any active autonomous transactions are explicitly committed > // or rolled back. > > ==> Aí, juntando com o texto do manual "Oracle® Database PL/SQL User's Guide > and Reference 10g" na entrada "AUTONOMOUS_TRANSACTION Pragma" chegamos na > ponto : a questão aqui é que vc está usando uma AUTONOMOUS TRANSACTION, e > esse tipo de processamento abre uma transação INDEPENDENTE da transação > principal, transação essa que TEM que ser encerrada (com COMMIT ou ROLLBACK), > por isso que vc recebeu o erro ORA-06519.... > E aí adivinho a sua pergunta, POR QUE vc não recebeu esse erro no outro banco > com esse código ?? Como eu disse na minha resposta anterior, SE REALMENTE as > versões dos dois databases estão RIGOROSAMENTE IGUAIS (até o 5o dígito!), SE > os one-off patches aplicados são os mesmos E SE o código da trigger é o MESMO > nos dois bancos, a resposta é que vc tem alguma diferença SOFT (muito > provavelmente nos DADOS) entre os dois databases..... Olhando o teu código, > eu vejo que o primeiro DML da rotina (que inicia a transação autônoma) é o > UPDATE, que está dentro de IFs : então o meu palpite é que no banco-origem > pro causda de dados diferentes do destino algum dos IFs não ficou verdadeiro, > portanto o UPDATE que inicia a transação marcada como Autônoma não foi > executado e Por Isso lá vc não recebeu o ORA-06519, enquanto aqui no > banco-destino os dados estavam Diferentes, aí os IFs ficaram verdadeiros, aí > o DML (UPDATE) foi executado e abriu a > transação, aí quando a procedure terminou sem comittar ou rollbackear a > transação autônoma que foi aberta vc recebeu o erro ORA-06519 - faz > sentido.... > > AGORA : entenda que AUTONOMOUS TRANSACTION é algo que é COMPLICADO de usar de > maneira correta e segura numa situação afora log de erros - procure em > http://asktom.oracle.com por AUTONOMOUS TRANSACTION que vc vai acahr n+1! > casos de mau uso e contra-recomendações... Eu FORTEMENTE recomendo que vc OU > altere esse modelo que exige query e/ou update na mesma tabela que sofreu o > INSERT, OU dispare um JOB via DBMS_JOB que faça a lógica necessária (que só > vai ser acionado pelo RDBMS quando do COMMIT na transação principal) OU > então (o melhor, IMHO, se não der pra alterar o modelo) que vc faça o INSERT > via API, ou seja : revoka os privilégios de INSERT na tabela, cria uma > procedure que faz o INSERT e os UPDATEs necessários e dá GRANT de execute na > procedure, apenas..... > > Só pra vc ficar ciente de UM dos riscos de se usar Autonomous Transaction > (sem ser para logs de erros), imagine aí no seu cenário que vc meteu um > commit no bloco com autonomous transaction : aí o seu usuário (via aplicação, > imagino) manda um INSERT (abrindo a transação principal, ok), aí em resultado > disso o trigger de INSERT dispara, o bloco com autonomous transaction faz um > DML, o DML é comitado (isso pode acontecer porque a a.t. é uma transação > INDEPENDENTE), legal - aí, digamos que o usuário NÂO CONFIRMA a transação > principal, DESFAZENDO o resultado do INSERT com um ROLLBACK , o que vc acha > que acontece ??? Eu respondo, Integridade Lógica JOGADA PELA JANELA , pois > como o Manual nos avisa, o ROLLBACK *** não vai *** desfazer o que foi feito > na a.t..... Assustador ? DEVERIA SER, já que a função BÁSICA de um RDBMS é > manter Integridade das informações, junto com um histórico lógico preciso do > que foi feito..... > Entre as muitas refs que vc vai achar no site doi asktom, eu destaco > http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2212445691154#2234749376635 > , que lista esses e outros perigos da Autonomous Transaction usada para > Qualquer Outro Fim que não seja criar uma tabela de log de erros/ações.... > > []s > > Chiappa > > > --- Em oracle_br@yahoogrupos.com.br, Elcio Francisco <elciofrancisco@> > escreveu > > > > Realmente o erro certo é ORA-6519. > > > > Estou colando a trigger ..So conseguimos resolver colocando COMMIT na > > trigger. Colocar COMMIT em trigger não é muito recomendado porque??? > > > > Obrigado > > > > create or replace trigger TRG_COMPART_TRAB_REFER > > after insert on crd.trab_referencia > > REFERENCING NEW AS NEW > > for each row > > declare > > Pragma Autonomous_Transaction; > > v_compartilha_cadastro crd.regras_negocio.compartilha_cadastro%type > > := null; > > v_empresa_origem crd.cliente.empresa_origem%type; > > v_cpf_cgc crd.cliente.cpf_cgc%type; > > v_debug varchar2(1000); > > > > --CURSOR PARA ATUALIZA¿¿O DO CADASTRO COMPARTILHADO > > cursor cur_dados_compart (pc_codcpf_cgc in crd.cliente.cpf_cgc%type, > > pc_empresa_origem in > > crd.cliente.empresa_origem%type) is > > select cli.empresa empresacli, cli.cliente, cli.empresa_origem, > > cli.loja_origem, > > rn.empresa , rn.compartilha_cadastro > > from crd.cliente cli, crd.regras_negocio rn > > where cli.cpf_cgc = pc_codcpf_cgc > > and cli.empresa_origem = rn.empresa > > and cli.empresa_origem NOT IN (pc_empresa_origem) > > and rn.compartilha_cadastro = 'S'; > > reg_dados_compart cur_dados_compart%rowtype; > > begin > > > > begin > > select cli.cpf_cgc, cli.empresa_origem, rn.compartilha_cadastro > > into v_cpf_cgc, v_empresa_origem, v_compartilha_cadastro > > from crd.cliente cli, crd.regras_negocio rn > > where cli.empresa = :NEW.EMPRESA > > and cli.cliente = :NEW.CLIENTE > > and cli.empresa_origem = rn.empresa; > > exception when others then > > v_compartilha_cadastro := 'N'; > > end; > > > > if user <> 'REPADMIN' then > > IF INSERTING THEN > > if(v_compartilha_cadastro = 'S') then > > > > open cur_dados_compart(v_cpf_cgc, v_empresa_origem); > > loop > > fetch cur_dados_compart into reg_dados_compart; > > exit when cur_dados_compart%notfound; > > begin > > UPDATE crd.trab_referencia > > SET PAI = :NEW.PAI, > > MAE = :NEW.MAE, > > TRABALHO = :NEW.TRABALHO, > > LOGRADOURO = :NEW.LOGRADOURO, > > ENDERECO = :NEW.ENDERECO, > > NUMERO = :NEW.NUMERO, > > COMPLEMENTO = :NEW.COMPLEMENTO, > > BAIRRO = :NEW.BAIRRO, > > CIDADE = :NEW.CIDADE, > > UF = :NEW.UF, > > CEP = :NEW.CEP, > > TELEFONE = :NEW.TELEFONE, > > CELULAR = :NEW.CELULAR, > > ENVIA_E_MAIL = :NEW.ENVIA_E_MAIL, > > E_MAIL = :NEW.E_MAIL, > > SALARIO = :NEW.SALARIO, > > RENDA = :NEW.RENDA, > > RENDA_NOMINAL = :NEW.RENDA_NOMINAL, > > ADMISSAO = :NEW.ADMISSAO, > > CGC_SOCIED = :NEW.CGC_SOCIED, > > CAPITAL_SOC = :NEW.CAPITAL_SOC, > > COTAS_SOC = :NEW.COTAS_SOC, > > RESIDENCIA_SITUACAO = :NEW.RESIDENCIA_SITUACAO, > > TEMPO_RESIDENCIA = :NEW.TEMPO_RESIDENCIA, > > VAL_ALUGUEL = :NEW.VAL_ALUGUEL, > > TELEFONE_SITUACAO = :NEW.TELEFONE_SITUACAO, > > QTD_DEPENDENTES = :NEW.QTD_DEPENDENTES, > > CARTOES_CREDITO = :NEW.CARTOES_CREDITO, > > MARCA_VEICULO = :NEW.MARCA_VEICULO, > > MODELO_VEICULO = :NEW.MODELO_VEICULO, > > ANO_VEICULO = :NEW.ANO_VEICULO, > > REF1_PESSOAL = :NEW.REF1_PESSOAL, > > END1_REF_PESSOAL = :NEW.END1_REF_PESSOAL, > > TEL1_REF_PESSOAL = :NEW.TEL1_REF_PESSOAL, > > REF2_PESSOAL = :NEW.REF2_PESSOAL, > > END2_REF_PESSOAL = :NEW.END2_REF_PESSOAL, > > TEL2_REF_PESSOAL = :NEW.TEL2_REF_PESSOAL, > > BCO1_BANCO = :NEW.BCO1_BANCO, > > BCO1_AGENCIA = :NEW.BCO1_AGENCIA, > > BCO1_CONTA = :NEW.BCO1_CONTA, > > BCO2_BANCO = :NEW.BCO2_BANCO, > > BCO2_AGENCIA = :NEW.BCO2_AGENCIA, > > BCO2_CONTA = :NEW.BCO2_CONTA, > > AUTORIZA_DEBITO = :NEW.AUTORIZA_DEBITO, > > RENDA_FAMILIAR = :NEW.RENDA_FAMILIAR, > > VAL_COTAS_SOC = :NEW.VAL_COTAS_SOC, > > DATA_FUNDACAO_SOC = :NEW.DATA_FUNDACAO_SOC, > > SITUACAO_VEICULO = :NEW.SITUACAO_VEICULO, > > VALOR_VEICULO = :NEW.VALOR_VEICULO, > > BCO1_TIPO_CONTA = :NEW.BCO1_TIPO_CONTA, > > BCO2_TIPO_CONTA = :NEW.BCO2_TIPO_CONTA, > > BCO1_CLI_DESDE = :NEW.BCO1_CLI_DESDE, > > BCO2_CLI_DESDE = :NEW.BCO2_CLI_DESDE, > > GRAU_INSTRUCAO = :NEW.GRAU_INSTRUCAO, > > APRESENTOU_END = :NEW.APRESENTOU_END, > > RAMAL1_REF_PESSOAL = :NEW.RAMAL1_REF_PESSOAL, > > RAMAL2_REF_PESSOAL = :NEW.RAMAL2_REF_PESSOAL, > > POSSUI_SEGURO = :NEW.POSSUI_SEGURO, > > TIPO_RENDA_PRESUMIDA = :NEW.TIPO_RENDA_PRESUMIDA, > > VALOR_RENDA_PRESUMIDA = > > :NEW.VALOR_RENDA_PRESUMIDA, > > QTD_PRESTACAO_PRESUMIDA = > > :NEW.QTD_PRESTACAO_PRESUMIDA, > > EMPRESA_USUARIO = :NEW.EMPRESA_USUARIO, > > TIPO_RENDIMENTO = :NEW.TIPO_RENDIMENTO, > > TEMPO_TRABALHO = :NEW.TEMPO_TRABALHO, > > TEMPO_RESIDENCIA1 = :NEW.TEMPO_RESIDENCIA1, > > TIPO_LOG_CEP = :NEW.TIPO_LOG_CEP, > > CELULAR_REF1_PESSOAL = :NEW.CELULAR_REF1_PESSOAL, > > CELULAR_REF2_PESSOAL = :NEW.CELULAR_REF2_PESSOAL > > WHERE EMPRESA = > > reg_dados_compart.empresacli > > and CLIENTE = > > reg_dados_compart.cliente; > > exception when others then > > --rollback; > > htp.print('erro'); > > --v_debug := > > utl_http.request('http://multi02/multicredito/debug/teste.php?data=:' || > > replace(sqlerrm, ' ', '_')); > > end; > > end loop; > > close cur_dados_compart; > > > > COMMIT; > > end if; > > END IF; > > end if; > > > > end TRG_COMPART_TRAB_REFER; > > > > Elcio Francisco > > Analista de Sistemas > > Multicrédito > > Belo Horizonte - MG > > > > P Antes de imprimir pense em sua responsabilidade com o MEIO AMBIENTE > > Adote os 3Rs na sua vida: Reduza, Reutilize, Recicle! > > > > > > ________________________________ > > De: J. Laurindo Chiappa <jlchiappa@> > > Para: oracle_br@yahoogrupos.com.br > > Enviadas: Segunda-feira, 26 de Agosto de 2013 16:49 > > Assunto: [oracle_br] Re: ORA-06159 > > > > > > > > > > Bem, algumas obs que talvez te ajudem : > > > > - plz CERTIFIQUE-SE que é erro é mesmo ORA-06159 : digo isso porque numa > > busca rápida por error 06159, só achei RMAN-06159, o que não tem nada a ver > > com programação... Como eu disse, Confirme que é "ORA" o prefixo E > > REALMENTE é 06159 o código... > > > > - SE o código (e os dados!!) estão Absolutamente, totamente, Completamente > > IGUAIS nos dois databases, E os databases são idênticos (ie, mesma versão, > > mesmo tipo de instalação e config. , mesmas features ativadas/instaladas, > > etc, etc), isso parece indicar que aí é alguma diferença de ambiente, tais > > como (entre muitas outras) permissões, database links apontando para > > destinos diferentes, coisas assim... > > > > => A Recomendação é uma só : usando sqlplus (para eliminarmos as > > possibilidades de problemas relacionadas à tool cliente) monte um > > caso-exemplo o mais curto possível MAS que dê o erro e nos mostre, ALÉM de > > explicar um pouco o seu ambiente , okdoc ?? PRINCIPALMENTE queremos ver > > aqui o error stack (ie, mas msgs todas de erro) E saber um pouco das > > transações e condições que estão presentes quando dá o erro ... > > > > []s > > > > Chiappa > > > > --- Em oracle_br@yahoogrupos.com.br, Elcio Francisco <elciofrancisco@> > > escreveu > > > > > > Bom dia estou com problema em uma trigger. Erro ORA-06159 porem essa > > > trigger é igual a uma outra que ja funciona. Ja olhamos tudo e não tem > > > diferencia nenhuma da que funciona. > > > Estou precisando de ajuda. > > > > > > Obrigado > > > > > > Oracle Database 10g Release 10.2.0.4.0 - Production > > > PL/SQL Release 10.2.0.4.0 - Production > > > CORE10.2.0.4.0Production > > > TNS for 32-bit Windows: Version 10.2.0.4.0 - Production > > > NLSRTL Version 10.2.0.4.0 - Production > > > > > > Elcio Francisco > > > > > > [As partes desta mensagem que não continham texto foram removidas] > > > > > > > > > > > > > [As partes desta mensagem que não continham texto foram removidas] > > > > > > > [As partes desta mensagem que não continham texto foram removidas] >