Na verdade, é exatamente assim que as transações aninhadas foi projetado para. Eu cito de documentos oracle:
Portanto, uma transação filha em uma transação aninhada regular não tem nada a dizer sobre como ele ou os outros filhos ou pais (transação maior ) poderia se comportar, além de alterar dados mútuos ou falhar por uma exceção.
Mas você pode conceder a ele (transação filha ) uma chance de voto muito limitada em seu destino, utilizando a
sub-transaction
recurso conforme declarado em rails docs
passando requires_new: true
User.transaction do
User.create(username: 'Kotori')
User.transaction(requires_new: true) do
User.create(username: 'Nemu')
raise ActiveRecord::Rollback
end
end
Que como dizem os documentos:apenas cria 'Kotori'. desde que a poderosa criança 'Nemu' escolheu morrer silenciosamente.
Mais detalhes sobre Regras de transações aninhadas (documentos oracle )
Atualização:
Para entender melhor por que Rails
nested transactions
funciona dessa maneira, você precisa saber um pouco mais sobre como as transações aninhadas funcionam no nível do banco de dados, cito documentos da API Rails
:Ok, então a documentação descreve o comportamento de uma
nested transaction
nos dois casos mencionados da seguinte forma:No caso de uma chamada aninhada, #transaction vai se comportar da seguinte forma:
-
O bloco será executado sem fazer nada. Todas as instruções de banco de dados que ocorrem dentro do bloco são efetivamente anexadas à transação de banco de dados já aberta.
-
No entanto, se :requires_new estiver definido, o bloco será encapsulado em um ponto de salvamento do banco de dados atuando como uma subtransação.
Imagino cuidado, apenas imagine que:
opção(1) (sem require_new) existe caso você tenha usado um DBMS que suporte totalmente
nested transactions
ou você está satisfeito com o comportamento "falso" de nested_attributes
enquanto opção(2) é suportar o
savepoint
solução alternativa se você não fizer isso.