PHP PDO Transaction Management across multiple write methods on different classes -


i need architecting appropriate approach managing transaction across multiple writes on multiple data access methods on different classes.

consider following example code.

pdo connection class

class dbservice {     private static $instance = null;     public static function connect() {         if(self::$instance === null) {             try {                 self::$instance = new pdo("mysql:host=myservername;dbname=mydbname", 'myusername', 'mypassword');            } catch (\exception $e) {                return null;            }         }         return self::$instance;     }      protected function __construct() {} // prevent creating new instance (faking singleton) } 

order repository database access

class orderrepository {     public static function insert($data) {         $con = dbservice::connect();         $stmt = $con->prepare('insert orders (customer_id, order_date) values (:custid, now())');         $stmt->execute(array(':custid'=>$data['custid']));         return $con->lastinsertid();     } } 

orderdetailrepository (lineitems) order's products

class orderdetailrepository {     public static function insert($data) {         $con = dbservice::connect();         $stmt = $con->prepare('insert orderdetails (order_id, product_id, quantity) values (:orderid, :prodid, :qty)');         $stmt->execute(array(':orderid'=>$data['orderid'],  ':prodid'=>$data['prodid'], ':qty'=>$data['qty']));         return $con->lastinsertid();     } } 

the service class handle logic of creating order (ie order entry + order detail entry). need understanding how implement transaction if there error in 2nd insert (order details) can rollback work done inserting order table.

class orderservice {     public static function createorder($data) {        try {            $orderid = orderrepository::insert($data);            $orderdetailid = orderdetailrepository::insert($data);             // commit transaction        } catch (\exception $e) {            // roll transaction            return false;        }        return true;     } } 

i tried make question succinct code example minimalistic make it. still apologize verboseness.

thanks

simply wrap transaction around control flow of activities, in case in orderservice->createorder() method

class orderservice {     public static function createorder($data) {        try {            $con = dbservice::connect();            $con->begintransaction();             $orderid = orderrepository::insert($data);            $orderdetailid = orderdetailrepository::insert($data);             // commit transaction            $con->commit();        } catch (\exception $e) {            // roll transaction            $con->rollback();            return false;        }        return true;     } } 

or move level , around call orderservice->createorder()

the method can simplified to

class orderservice {     public static function createorder($data) {        $orderid = orderrepository::insert($data);        $orderdetailid = orderdetailrepository::insert($data);     } } 

your main processing loop

try {     $con = dbservice::connect();     $con->begintransaction();      $orderservice->createorder($data);      $con->commit();  } catch (\exception $e) {     // roll transaction     $con->rollback(); } 

Comments

Popular posts from this blog

serialization - Convert Any type in scala to Array[Byte] and back -

matplotlib support failed in PyCharm on OSX -

python - Matplotlib: TypeError: 'AxesSubplot' object is not callable -