Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Icepick.pt

Transação com PDO - não realizada

Mensagens Recomendadas

Icepick.pt

Olá pessoal

Tenho estado a utilizar o PDO para interagir com a base de dados, e ultimamente tenho começado a utilizar tramsações para impor a execução de várias operações de uma vez só.

No script em anexo estou a ter uma dificuldade:

- as queries de SQL estão correctas, se eu não as espatifar tudo corre bem e ambas as operações são escritas na base de dados-

- se eu espatifar uma das queries, era de esperar que a outra querie não fosse executada, uma vez que estamos dentro de uma transação. Contudo, o facto é que a exceção é identificada, o erro é reportado no echo final, mas a querie correcta acaba por ser escrita na mesma, em lugar de ser feito o rollback.

Alguem me explica porquê?

try {
    // habilita as excepções
   $dbwrite->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   // inicia a transacção
   $dbwrite->beginTransaction();

   // realiza a primeira operação de escrita
   $stringUpdate="
      update tabela1
	  set campo1= :conteudo1_, campo2= :conteudo2_, campo3= :conteudo3_
	  where umaCondicaoQualquer ";

   $pedido=NULL;
   $pedido=$dbwrite->prepare($stringUpdate);
      // limpa as variáveis que vai escrever na bd
   $pedido->bindParam(':conteudo1_', $_POST['post1'], PDO::PARAM_INT);
   $pedido->bindParam(':conteudo2_', $_POST['post2'], PDO::PARAM_INT);
   $pedido->bindParam(':conteudo3_', $_POST['post3'], PDO::PARAM_STR);
   $pedido->execute();

   // realiza a segunda operação de escrita
   $stringUpdate="
		 update tabela2
		 set campoA= :conteudoA_,  campoB= :conteudoB_,  campoC= :conteudoC_
		 where outraCondicaoQualquer";

   $pedido=NULL;
   $pedido=$dbwrite->prepare($stringUpdate);
      // limpa as variáveis que vai escrever na bd
   $pedido->bindParam(':conteudoA_', $_POST['postA'], PDO::PARAM_INT);
   $pedido->bindParam(':conteudoB_', $_POST['postB'], PDO::PARAM_INT);
   $pedido->bindParam(':conteudoC_', $_POST['postC'], PDO::PARAM_STR);
   $pedido->execute();

   // finaliza a escrita das duas operações
   $dbwrite->commit();
    }

// se ocorreu uma excepção
catch (Exception $e) {
   // desfaz toda a operação
   $dbwrite->rollBack();
   echo $e;
   }

Editado por Icepick.pt

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

Alguem me explica porquê?

Sem indentacao é dificil perceber o codigo :(


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mjamado

Qual é o motor usado nas tabelas?


"Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Icepick.pt

Não sei porquê, não consigo transpor as tabulações do notepad++ para aqui. Já coloquei espaços, mas não está muito melhor.

O motor é MySQL.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Não sei porquê, não consigo transpor as tabulações do notepad++ para aqui.

alterna o modo de edição do post, no primeiro botão do editor da resposta, para poderes colocar código sem perda de indentação


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Icepick.pt

Aí vai i código agora, correctamente indentado ( digo eu...)

Obrigado, yoda.

try {
// habilita as excepções
$dbwrite->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// inicia a transacção
$dbwrite->beginTransaction();

// realiza a primeira operação de escrita
$stringUpdate="
	update tabela1
	set campo1= :conteudo1_, campo2= :conteudo2_, campo3= :conteudo3_
	where umaCondicaoQualquer ";

$pedido=NULL;
$pedido=$dbwrite->prepare($stringUpdate);
// limpa as variáveis que vai escrever na bd
$pedido->bindParam(':conteudo1_', $_POST['post1'], PDO::PARAM_INT);
$pedido->bindParam(':conteudo2_', $_POST['post2'], PDO::PARAM_INT);
$pedido->bindParam(':conteudo3_', $_POST['post3'], PDO::PARAM_STR);
$pedido->execute();

// realiza a segunda operação de escrita
$stringUpdate="
	update tabela2
	set campoA= :conteudoA_, campoB= :conteudoB_, campoC= :conteudoC_
	where outraCondicaoQualquer";

$pedido=NULL;
$pedido=$dbwrite->prepare($stringUpdate);
// limpa as variáveis que vai escrever na bd
$pedido->bindParam(':conteudoA_', $_POST['postA'], PDO::PARAM_INT);
$pedido->bindParam(':conteudoB_', $_POST['postB'], PDO::PARAM_INT);
$pedido->bindParam(':conteudoC_', $_POST['postC'], PDO::PARAM_STR);
$pedido->execute();

// finaliza a escrita das duas operações
$dbwrite->commit();
}
// se ocorreu uma excepção
catch (Exception $e) {
// desfaz toda a operação
$dbwrite->rollBack();
// apresenta a excepção
echo $e;
}

Editado por yoda

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
mjamado
O motor é MySQL.

O MySQL não é um motor, é o DBMS. O motor há-de ser MyISAM, InnoDB, Memory... Qual é?


"Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Icepick.pt

Boa, mjamado!

Uma das tabelas era MyISAM e a outra era InnoDB.

Mudei a que era MyISAM para InnoDB et voilá, a transação já funciona.

Claro que depois fui pesquisar a net nesta perspectiva e encontrei a resposta: O motor MyISAM não suporta transações.

http://en.wikipedia.org/wiki/MyISAM

Obrigado.

Editado por Icepick.pt

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.