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
Post a Comment