Transação com SingleTon
Senhores,
Este é o meu primeiro post neste forúm...
O Problema é o seguinte:
Tenho uma conexão PDO no padrão SingleTon, porém não consigo controlar as transações.
Se inicio uma transação e executo dois updates, sendo que o primeiro esta tudo correto e o segundo forçando um erro, mesmo caindo no roolback o primeiro update é commitado..
Segue a baixo todos os códigos:
<?php
/**
* TConn.class [ CONEXÃO ]
* Classe abstrata de conexão. Padrão SingleTon.
* Retorna um objeto PDO pelo método estático getConn();
* @copyright (c) 2018, Carlos Junior
*/abstract class TConn {
private static $Host = HOST;
private static $User = USER;
private static $Pass = PASS;
private static $Dbsa = DBSA;
private static $Type = TYPE;
/** @var PDO */
private static $Connect = null;
/* * ************************************************ */
/* * ************* METODOS PRIVADOS ***************** */
/* * ************************************************ */
/**
* Conecta com o banco de dados com o pattern singleton.
* Retorna um objeto PDO!
*/
private static function Conectar() {
try {
if (self::$Connect == null) :
switch (self::$Type) {
case 'mysql':
$dsn = 'mysql:host=' . self::$Host . ';dbname=' . self::$Dbsa;
$options = [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'];
self::$Connect = new PDO($dsn, self::$User, self::$Pass, $options);
break;
case 'sqlite':
$dsn = 'sqlite:' . self::$Dbsa;
self::$Connect = new PDO($dsn);
case 'ibase':
$dsn = 'firebird:dbname=' . self::$Dbsa;
self::$Connect = new PDO($dsn, self::$User, self::$Pass);
break;
default:
$dsn = 'mysql:host=' . self::$Host . ';dbname=' . self::$Dbsa;
$options = [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'];
self::$Connect = new PDO($dsn, self::$User, self::$Pass, $options);
break;
}
endif;
} catch (PDOException $e) {
PHPErro($e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine());
}
self::$Connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return self::$Connect;
}
/** Retorna um objeto PDO Singleton Pattern. */
protected static function getConn() {
return self::Conectar();
}
/* * ************************************************ */
/* * ************* METODOS PUBLICOS ***************** */
/* * ************************************************ */
}
<?php
/**
* TConn.class [ TRANSAÇÃO ]
* Classe final de Transação.
* Inicia uma transação no banco de dados
* @copyright (c) 2018, Carlos Junior
*/
final class TTransaction extends TConn {
/ ************************************************ */
/ *********** METODOS PRIVADOS *************** */
/ ************************************************ */
/** @var PDO */
private static $Conn;
/* Método __construct()
* Está declarado como private para impedir que se crie uma instância de TTransaction
*/
private function __construct() {}
/* * ************************************************ */
/* * ************* METODOS PUBLICOS ***************** */
/* * ************************************************ */
public static function Open() {
if (empty(self::$Conn)):
self::$Conn = parent::getConn();
endif;
self::$Conn->beginTransaction();
}
public static function Get() {
return self::$Conn;
}
public static function Rollback() {
if (self::$Conn):
self::$Conn->rollBack();
self::$Conn = NULL;
endif;
}
public static function Close() {
if (self::$Conn):
self::$Conn->commit();
self::$Conn = NULL;
endif;
}
}
<?php
/**
* TSQLUpdate.class [ SQLInstruction ]
* Esta classe provê meios para manipulação de uma instrução de UPDATE no banco de dados
* @copyright (c) 2018, Carlos Junior
*/class TSQLUpdate extends TSqlInstruction {
private $Dados; // Array com o Dados para Instrução
public $Result;
/* * ************************************************ */
/* * ************* METODOS PRIVADOS ***************** */
/* * ************************************************ */
/** <b>Metodo getInstruction</b>
* Retorna a instrução de UPDATE em forma de string
* @return string Instrução SQL- UPDATE
* */
protected function getInstruction() {
$this->Sql = "UPDATE {$this->Entity}";
//monta os pares; coluna=valor,...
if ($this->Dados):
foreach ($this->Dados as $column => $value) {
$set[] = "{$column} = :{$column}";
}
$this->Sql .= ' SET ' . implode(', ', $set);
//retorna a clausula WHERE do objeto $this->Criterio
if ($this->Criterio):
$this->Sql .= ' WHERE ' . $this->Criterio->dump();
endif;
endif;
}
/* * ************************************************ */
/* * ************* METODOS PUBLICOS ***************** */
/* * ************************************************ */
/** <b>Metodo __construct</b>
* Instancia um novo objetio do tipo SQLUpdate
* @param String $Entity = 'Nome da Tabela'
* @param Array $Dados = Array associativo com os dados a serem alterados [campo => valor]
* */
public function __construct($Entity, $Dados, TCriterio $Criterio) {
$this->Entity = (string) $Entity;
$this->Dados = (array) $Dados;
if (!$Criterio):
WSErro("<b>Critério do objeto TSQLUpdate não foi informado:</b>", 999);
die;
else:
$this->setCriterio($Criterio);
endif;
}
/** <b>Metodo Execute</b>
* Executa uma instrução UPDATE no banco de dados
* @return Result = Retorna na propriedade [Result] se os dados foram alterados [True ou False]
* */
public function Execute() {
$this->getInstruction();
parent::Connect();
try {
parent::$Statement->execute($this->Dados);
$this->Result = True;
} catch (PDOException $e) {
WSErro("<b>Erro ao executar a atualização:</b> {$e->getMessage()}", $e->getCode());
}
}
}
<?php
include_once './PROJETO/APP.CONFIG/Config.inc.php';
try {
TTransaction::Open();
$conn = TTransaction::Get();
$famosos = ['nome' => 'Samuel Henrique'];
$criterio = new TCriterio();
$criterio->add(new TFilter('codigo', '=', 8));
$update = new TSQLUpdate('famosos', $famosos, $criterio);
$update->Execute();
if ($update->Result):
echo "1 update Alterado com sucesso..";
endif;
$famosos = ['nome_' => 'Maria Eugenia dos Santos'];
$criterio = new TCriterio();
$criterio->add(new TFilter('codigo', '=', 7));
$update = new TSQLUpdate('famosos', $famosos, $criterio);
$update->Execute();
if ($update->Result):
echo "2 update Alterado com sucesso..";
endif;
TTransaction::Close();
} catch (Exception $exc) {
TTransaction::Rollback();
echo $exc->getTraceAsString();
}Discussão (4)
Carregando comentários...