Se você olhar apenas para o banco de dados, tudo está bem. Você tem transações e, se algo der errado, tudo é revertido. Isso é bom - eu gosto disso.
MAS: Eu quero enviar e-mails. Agora estou com problemas porque não consigo reverter.
exemplo:
- transação começa
- O correio é enviado
- Outras coisas são feitas (dentro do DB)
- Algo dá errado.
- Reverter.
Como resolver isso é uma questão diferente, não essa.
Esta questão como chamar isso em geral. Neste exemplo é sobre o envio de e-mails. Mas o mesmo problema assim que você modifica algo em sistemas que estão fora do limite da transação.
Existe um nome para este problema ?
Aproximadamente o mesmo problema surge se você deseja importar arquivos de um diretório. Se você excluir o arquivo dentro da transação, a transação poderá falhar e o arquivo foi excluído, mas nunca importado. Ou você exclui o arquivo após a transação. Em seguida, a exclusão do arquivo pode falhar e o arquivo é importado uma segunda vez.
Não quero reinventar uma solução para isso. É por isso que preciso do termo correspondente para esse problema. Então eu posso ler alguns artigos e aprender o que é "estado da arte" no ano de 2018.
A palavra- chave Oracle PL/SQL
AUTONOMOUS_TRANSACTION
fará com que um procedimento crie outra sessão, faça uma transação, confirme/reverta apenas essa transação privada e retorne o controle de fluxo de volta ao pai.Oh..nunca envie e-mail sobre dados não confirmados.
EDIT: (devido à edição do post original)
Esse tipo de problema é chamado de
bug
.A solução é:
TRANSACTION
COMMIT
.Exemplo de e-mail
Você deve ter um procedimento
sendEmail
que deve ser chamado apóscommit
.Se você quiser chamar o procedimento antes de
commit
, precisará adicionar uma linha a uma fila querollback
acompanhará a transação principal. Para Oracle, isso seráAdvance Queuing
ou o pacoteAPEX_MAIL
Ao colocá-lo em um procedimento separado, você pode fazer
sendEmail
uma segunda vez a pedido do [usuário final].Arquivo de processo
Você tem um algoritmo que contém algumas etapas em que cada etapa pode falhar. isso é realmente diferente do seu
sendEmail
problema.Você precisa registrar o que está processando, onde está no seu algoritmo e se essa etapa foi bem-sucedida ou falhou.
Para se recuperar de um erro em qualquer etapa, cada etapa do processo precisa ser definida como um
TRANSACTION
.No Oracle, eu teria esses procedimentos (1 procedimento por
TRANSACTION
):Isso é baseado nas seguintes tabelas:
A
UNIQUE
restrição onFILE_NAME
impede que o mesmo arquivo seja processado duas vezes.Acho que talvez o termo que você está procurando seja leitura suja :
Você está descrevendo uma transação distribuída . Observe que o termo "transação" tem um significado mais geral do que simplesmente "transação de banco de dados".
Em uma transação distribuída, diferentes membros podem ter diferentes propriedades ACID (por exemplo, e-mail não é necessariamente garantido para ser entregue), diferentes abordagens para alcançar essas propriedades e diferentes cenários de falha.
Para garantir a consistência de uma transação distribuída, uma entidade externa chamada coordenador de transação (ou gerente) é normalmente empregada para controlar o comprometimento de cada membro (também pode ser chamado de recurso ou gerenciador de recursos). Um método comum é o two-phase commit (2PC).
Se você pesquisar por "consistência em sistemas distribuídos" na internet, encontrará uma grande variedade de materiais sobre o assunto.
O que você descreve é o desejo de uma transação distribuída, só que você não tem um gerenciador de transações distribuído e nenhuma possibilidade de reversão. O mais fácil é usar a queue ( external ) ou o sql server broker para desacoplar o loop do envio real. Veja por exemplo: http://python-rq.org/
Não tenho um termo específico para a combinação real de invocar um processo externo de uma transação de banco de dados, mas classificaria esse problema como fortemente acoplado .
A raiz do problema é que você acoplou fortemente o envio do e-mail com a transação do banco de dados.
Uma solução para este problema será acoplá-los frouxamente .
Tecnicamente, você pode resolver isso de várias maneiras, em ordem aproximada de feio a bonito:
Compromissos implícitos
Eu acredito que é o termo que você está procurando. Estas são declarações que podem/podem e não irão aderir
Transactions
Oráculo
MySQL
Servidor SQL
database-ddls-and-implicit-commit
e o mais interessante Isto:
sp_send_dbmail (Transact-SQL)
O Workflow só precisa de atenção,
Ao invés de
TENTAR
(Capturar a contagem de linhas finais para uma variável B ou arquivo)
e se as variáveis A e B corresponderem, você saberá que há um erro.
Altere o fluxo de trabalho e tente usar o que você já tem a seu favor, comparação de variáveis etc.
Este é um problema que não foi considerado na fase de "Engenharia de Requisitos" do projeto. Não deve ser visto como um problema do sistema de banco de dados, porque o banco de dados está funcionando como deveria. O email é enviado porque (ainda) não faz parte da lógica de negócios correta.
É chamado de falha de lógica de negócios ou possivelmente até mesmo um problema de lógica de negócios .
Logíca de negócios
Referência: Business Logic (Wikipedia.org)
Falhas / problemas de lógica de negócios
Referência: Vulnerabilidades de lógica de negócios e alguns cenários comuns de falhas de lógica de negócios (Comunidade de segurança cibernética)
Referência: falhas comuns de lógica de negócios que comprometem a segurança do aplicativo (SecurityWeek.com)