Standard Singleton in simultaneous connections

Asked

Viewed 137 times

0

I’m developing a project and I made a class in the pattern Singleton to connect to the database:

<?
    class Conexao extends PDO {

        private static $instancia;

        public function __construct($dsn, $username = "", $password = ""){
            parent::__construct($dsn, $username, $password, array(
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
            ));
        }

        public function prepare($statement, $options = NULL){
            if (!isset($options))
                $options = array();
            $options += array(
                PDO::ATTR_STATEMENT_CLASS => array('Query')
            );

            return parent::prepare($statement, $options);
        }

        public static function getInstance(){
            if (!isset(self::$instancia)){
                try{
                    self::$instancia = new Conexao("mysql:host=localhost; dbname=meu_banco",
                        "meu_usuario", "minha_senha");
                } catch (Exception $e) {
                    throw new Exception("Ocorreu um erro ao conectar!<br />".$e->getMessage());
                }
            }

            return self::$instancia;
        }
    }

    class Query extends PDOStatement{
        function execute($bound_input_params = NULL): bool{
            try{
                return parent::execute($bound_input_params);
            } catch (PDOException $e){
                throw new Exception("
                    Query: ".$this->queryString."<br />
                    (".$e->getCode().") ".$e->getMessage()."<br />
                ");
            }
        }

    }
?>

At a certain point I needed to make a transaction to ensure the execution of multiple scripts, so I did it this way:

<?
    function salvar(){
        $this->validar();

        $conn = null;
        try{
            $conn = Conexao::getInstance();

            $conn->beginTransaction();

            $sql = "";
            if ($this->id == 0){
                $sql = "
                    INSERT INTO `PedidoCompra` (`idFormaPagamento`, `idFornecedor`, `dataPedido`)
                    VALUES (:idFormaPagamento, :idFornecedor, NOW())
                "; 
            } else{
                $sql = "
                    UPDATE `PedidoCompra` SET
                    `idFormaPagamento` = :idFormaPagamento, `idFornecedor` = :idFornecedor
                    WHERE `idPedidoCompra` = :id
                ";
            }

            $query = $conn->prepare($sql);
            if ($this->id != 0)
                 $query->bindValue(":id", $this->id, PDO::PARAM_INT);
            $query->bindValue(":idFormaPagamento", $this->formaPagamento->getId(), PDO::PARAM_INT);
            $query->bindValue(":idFornecedor", $this->fornecedor->getId(), PDO::PARAM_INT);
            $query->execute();

            if ($this->id == 0)
                $this->id = $conn->lastInsertId();

            foreach($this->transacoes as $transacao){
                $transacao->setIdPedidoCompra($this->id);
                $transacao->salvar();
            }

            foreach($this->itens as $item){
                $item->setIdPedido($this->id);
                $item->salvar();
            }

            $conn->commit();
        } catch (Exception $e){
            if ($conn != null)
                $conn->rollBack();
            throw $e;
        }
    }
?>

The pattern Singleton prevents me from creating multiple instances of an object, but if two people are connected simultaneously, the same instance will be used for the two connections?

My concern is that I give one rollBack us scripts of usuario1 and it also affects the scripts of usuario2.

The Doubt

  • 1

    You’ll only be able to use singleton in PHP when the script is running (or unless you have done some different configuration, but by default this is it), by the time the script stops running, all open instances are deleted. When there are 2 users in the same script still returns 2 instances, one for each session.

  • Related: https://answall.com/q/28172/57801

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.