Você está na página 1de 4

Begin Transaction não da rollback sozinho?

Bom dia,

Tenho o seguinte código:

Begin Transaction
While x <= Len(aDadosDest)

//==========================
// - Retira PA do Estoque
If x == 1 //Garanto para que rode apenas uma vez a remoção do
estoque
ExpA1 := {}
aAdd(ExpA1,{"D3_FILIAL" ,xFilial("SD3") ,})
aAdd(ExpA1,{"D3_TM" ,"505" ,})
aAdd(ExpA1,{"D3_COD" ,aDadosPA[x, 1] ,})
aAdd(ExpA1,{"D3_UM" ,aDadosPA[x, 2] ,})
aAdd(ExpA1,{"D3_LOCAL" ,aDadosPA[x, 3] ,})
aAdd(ExpA1,{"D3_QUANT" ,aDadosPA[x, 4] ,})
aAdd(ExpA1,{"D3_EMISSAO",dDataBase ,})
aAdd(ExpA1,{"D3_LOTECTL",aDadosPA[x, 5] ,})
aAdd(ExpA1,{"D3_DOC" ,cDoc ,})
MSExecAuto({|x,y| mata240(x,y)},ExpA1,ExpN2)
If !lMsErroAuto
LogMsg('', 0, 14, 1, '', '',"Movimentação PAxCP-1-OK")
Else
mostraerro()
EndIf
EndIf

// -
//==========================
// - Verifica se possui registro do CP ou KT no armazém novo

If chkST(aDadosDest[x, 1]) == .F.


CriaSB2(aDadosDest[x, 1],aDadosDest[x, 3])
EndIf

// -
//==========================
// - Inclui CP ou KT no Estoque
If !lMsErroAuto
ExpA1 := {}
aAdd(ExpA1,{"D3_FILIAL" ,xFilial("SD3") ,})
aAdd(ExpA1,{"D3_TM" ,"005" ,})
aAdd(ExpA1,{"D3_COD" ,aDadosDest[x, 1] ,})
aAdd(ExpA1,{"D3_UM" ,aDadosDest[x, 2] ,})
aAdd(ExpA1,{"D3_LOCAL" ,aDadosDest[x, 3] ,})
aAdd(ExpA1,{"D3_QUANT" ,aDadosDest[x, 4] ,})
aAdd(ExpA1,{"D3_EMISSAO",dDataBase ,})
aAdd(ExpA1,{"D3_LOTECTL",aDadosDest[x, 5] ,})
aAdd(ExpA1,{"D3_DOC" , cDoc2 ,})
aAdd(ExpA1,{"D3_DTVALID",aDadosDest[x, 6] ,})
MSExecAuto({|x,y| mata240(x,y)},ExpA1,ExpN2) <---AQUI OCORRE
O ERRO

If !lMsErroAuto
LogMsg('', 0, 14, 1, '', '',"Movimentação PAxCP-2-OK")
Else
mostraerro()
EndIf
Endif
x++
EndDo
End Transaction
Ele executa duas EXECAUTO, a primeira ocorre como deveria, a segunda não.
Porem eu coloquei as duas dentro de um BEGIN TRANSACTION para tentar
garantir que caso 1 das duas movimentações dessem erro, nenhum fosse
executada. Porem constatei que quando a segunda da erro a primeira, por ja ter
sido executada com sucesso, não recebe um rollback. Minha interpretação esta
errada sobre a função? Sabem o que aconteceu?

*Obs: Lendo este link ele fala sobre uma DisarmTransaction, será que dentro das
minhas validações de erro eu preciso forçar a finalização da transação ou isso é
redundante?

2 respostas
Patrick, bom dia.

Sim, você precisa dar um DisarmTransaction caso o mostraerro() seja


exibido. Com isso ele vai desfazer toda a transação.

Abraço,
Mas a regra do Begin Transaction não é DEU ERRO = ROLLBACK?
Ou só por que não deu um errorLog ele não da RollBack?

 — Patrick Zerbinatti   23 de Jan de 2020


o 1
Neste caso o que é o melhor, adicionar um DisarmTransaction() ou um
DisarmTransaction() e um Break?

 — Patrick Zerbinatti   23 de Jan de 2020


o 1
Adicionei um DisarmTransaction() e um Break e funcionou
perfeitamente. Mas ainda estou encabulado quanto ao BEGIN
TRANSACTION

 — Patrick Zerbinatti   23 de Jan de 2020


o PAtrick, Percebi em alguns execautos que tem uma confirmação da
transação dentro deles, então para prevenir esse tipo de coisa, quando
tenho execautos em cascata (como é o seu caso) eu volto desfazendo se
alguma não da certo, ou seja, se inclui um cliente e não inclui um contas
a receber, eu excluo o cliente via execauto também.

 
Claro, se o disarmtransaction não funcionar.

 — FELIPE CAIADO ALMEIDA   23 de Jan de 2020


o Eita, ai minha confiança no controle de transações foi por agua abaixo
kkkkkkk

 — Patrick Zerbinatti   23 de Jan de 2020


Mostrar todos os 6 comentários>
Adicionar comentário
 2
up down
Funciona e funciona corretamente.

O begin transaction e end transaction apenas informam quando começa e


termina a transação.

O próprio nome já diz isso... não tem qualquer controle sobre dar rollback.
Para isso, você tem que usar o comando DisarmTransaction.

Até entendi o seu ponto de vista... "se deu erro, era pra voltar a transação"
mas pare para olhar friamente: esse trecho de código não sabe que deu
erro! Imagine que você não estivesse usando ExecAuto... imagine que
fosse um teste ou inclusão "na mão"... como ele saberia se incluiu com
sucesso ou não?

Neste seu exemplo, a única coisa que está protegendo a transação é


garantindo que ela seja executada (com sucesso ou não) de forma
TOTAL... no caso se perder conexão, cair elétrica, etc, ele dai sim daria
rollback automático pois não chegou no final. O END TRANSACTION
implica em um COMMIT.

E sim, você tem que fazer o DisarmTransaction() e o recomendado é usar


o BREAK para cair fora do laço , caso contrário nesse seu código, mesmo
dando erro já no primeiro execauto, ele vai tentar executar o segundo...
mesmo com a transação disarmada. Usar o Break é justamente um dos
pontos que o SONARQUBE valida0Erro ao gerar mais de um documento
de entrada via execauto AJUDA:FA050NUM
1. 0Grava apenas dados do relacionamento em MVC
2. 0Programa para calcular impostos automaticamente de um produto
3. 0Descrição no Envio de TReport por e-mail
4. 0Alteração de Alçada de aprovação

Você também pode gostar