Eu tenho várias tabelas que possuem gatilhos que inserem registros em tabelas de enfileiramento e registro. O problema é que essas inserções fazem parte da mesma transação. Isso significa que qualquer DIU nas tabelas anteriores pode ser bloqueado por outro DIU que acione inserções na mesma fila, e aquele DIU que falhar não será registrado, pois essas inserções também serão revertidas.
Não me importo muito com entradas na fila onde o DIU desencadeador foi revertido; a fila é lida por algum processo que invalida/atualiza o cache e ações semelhantes. Caso algo tenha sido revertido, algum cache será atualizado com os mesmos dados. Nada demais.
O caso de negócios aqui é um site com um grande número de conjuntos que consistem em produtos únicos. Qualquer produto pode estar em até 15.000 conjuntos. Se o preço de um produto mudar, os preços de todos esses conjuntos precisam ser recalculados. Não quero fazer isso na mesma transação ao salvar o preço de um produto, porque isso levaria muito tempo e bloquearia muito o banco de dados, então enfileiro o recálculo.
Para registrar, há algumas ações que desejo registrar, mesmo ( especialmente ) se elas falharem. Eu não posso fazer isso agora.
Se fosse esse Oracle, que usei até pouco tempo atrás, eu teria usado PRAGMA AUTONOMOUS_TRANSACTION
para lidar com o insert em uma transação separada, que sempre confirmaria não importando o que a outra transação fizesse.
Posso emular esse comportamento usando tabelas MyISAM para os logs e as filas, com concurrent_insert
definido como ALWAYS
, enquanto o restante das minhas tabelas são InnoDB? (Espero várias inserções neles, esse é o problema , embora raramente sejam lidos (logs) ou apenas uma vez (filas)).
Se você tiver acesso ao mecanismo Aria ou outro mecanismo não transacional, sim.
Prova de conceito muito curta, testada no MariaDB 10.5.4:
O transacional no Aria não é para transações reais, é apenas o último log de operação, ainda bom em caso de falha do servidor, os dados são consistentes.
Agora crie uma tabela InnoDB:
E teste:
Depois que o ROLLBACK foi iniciado, vamos verificar o conteúdo das tabelas Aria e InnoDB:
Portanto, ROLLBACK não pode reverter o mecanismo ARIA
Portanto, na tabela InnoDB, o ROLLBACK fez seu trabalho.
Isso mostra como evitar a lógica de transação no MariaDB ou usando um mecanismo semelhante como o MyISAM no MySQL.
Se possível, ouça o mantra: "Não faça fila, apenas faça."
Caso contrário, mantenha o código de enfileiramento e normalização fora das transações principais.
Quanto ao registro, não acho que haja outra solução além de gravar em uma tabela MyISAM para o seu registro.
Voltando a sua pergunta...
Não há como no MySQL ter transações aninhadas e independentes na mesma conexão. Duas conexões permitiriam isso, mas isso poderia ser confuso por outros motivos.