I'm using this class to handle my pdo connection and database actions, however I can't get the rollback function to work. I create an intentional error at the $pers-query, get the following error:
( ! ) Warning: PDO::query(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'webbshop.prson' doesn't exist in C:\wamp\www\webbshop\includes\db_con.php on line 21
but the other 2 querys are still executed, added to the database, and not rolled back. How do I do to get it all to work?
I read at another post that you need to use InnoDB so I ran the SHOW ENGINES sql command, and it said that support for InnoDB was default and the comment said: "Supports transactions, row-level locking, and foreign keys"
the PDO connection class:
<?php
class DB{
private $db_host = "localhost";
private $db_usr = "root";
private $db_pass = "";
private $db_name = "webbshop";
private $db;
function __construct(){
$this->db = new PDO('mysql:host=' . $this->db_host . ';'
.'dbname=' . $this->db_name, $this->db_usr, $this->db_pass);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
}
function error(){
} €$€$£
function Trans(){
$this->db->beginTransaction();
}
function insert($sql){
$stmt = $this->db->query($sql);
}
function fetch($sql){
$stmt = $this->db->prepare($sql);
$stmt->execute();
return $stmt->fetchAll();
}
function lastInsertID() {
return $this->db->lastInsertId();
}
function commitTrans(){
$this->db->commit();
}
function rollback() {
$this->db->rollBack();
}
function __destruct() {
$this->db = null;
}
}
And this is the code I use to execute the querys:
<?php
require 'db_con.php';
try {
$db = new DB();
$db->Trans();
$db->insert("INSERT INTO `webbshop`.`user` (`userID`, `nick`, `pass`) VALUES (NULL, '$_POST[nick]', '$_POST[pass]')");
$nickID = $db->lastInsertID();
echo $nickID;
$pers = "INSERT INTO `webbshop`.`prson` (`personID`, `userID`, `fname`, `lname`, `persnr`, `email`) VALUES (NULL, $nickID, '$_POST[firstname]', '$_POST[lastname]', '$_POST[personnr]','$_POST[email]')";
$addr = "INSERT INTO `webbshop`.`address` (`addressID`, `userID`, `street`, `city`, `zip`) VALUES (NULL, $nickID, '$_POST[address]', '$_POST[city]', '$_POST[zip]')";
$db->insert($pers);
$db->insert($addr);
$db->commitTrans();
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "</br>";
$db->rollback();
}
Are you using InnoDB? To use transactions you should use InnoDB or rollback won't work!
EDIT:
try to change PDO::ERRMODE_WARNING to PDO::ERRMODE_EXCEPTION
This problem make me crazy and I want to help u with my solution.The main problem is we call transaction from another class.
The important thing is using InnoDB and setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)and lastly your connection have to be open singleton function.
My code is:
class PDO_db{ protected static $_conn;
--[ CONNECTION ]--
public function __construct(){
if(empty(self::$_conn)){
try{
self::$_conn = new PDO("mysql:host=".DB_SERVER.";dbname=".DB_NAME, DB_USERNAME, DB_PASSWORD, array(PDO::MYSQL_ATTR_INIT_COMMAND=>"SET NAMES 'UTF8'"));
self::$_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
die("No Connection :: ".DB_NAME." : ".$e->getMessage());
}
}else{
return self::$_conn;
}
}
--[ TRANSACTION ]--
public static function Trans(){
return self::$_conn->beginTransaction();
}
--[ COMMIT ]--
public static function Commit(){
return self::$_conn->commit();
}
--[ ROLLBACK ]--
public static function Rollback(){
return self::$_conn->rollBack();
}
--[ INSERT ]--
public static function Insert($tablo, $rows){
}
}
class db{
public function __construct(){
$this->prodb = new PDO_db();
}
public function datainsert(){
$this->prodb->Trans();
try{
$datainsert = $this->prodb->Insert($table, $data);
$this->prodb->Commit();
$message = "Insert True";
return $message;
}catch(Exception $ex){
$this->prodb->Rollback();
$message = "Insert Flase";
return $message;
}
}
}