2016-09-07 4 views
1

異なるクラスの複数のデータアクセスメソッドに対する複数の書き込みにわたってトランザクションを管理するための適切なアプローチを設計するのに役立つ必要があります。異なるクラスの複数の書き込みメソッド間のPHP PDOトランザクション管理

次のサンプルコードを検討してください。

PDO接続クラス

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 a singleton) 
} 
作成のロジックを処理するための製品

class OrderDetailRepository { 
    public static function insert($data) { 
     $con = DBService::connect(); 
     $stmt = $con->prepare('INSERT INTO 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(); 
    } 
} 

サービスクラスのためのデータベース・アクセス

class OrderRepository { 
    public static function insert($data) { 
     $con = DBService::connect(); 
     $stmt = $con->prepare('INSERT INTO Orders (customer_id, order_date) VALUES (:custId, NOW())'); 
     $stmt->execute(array(':custId'=>$data['custId'])); 
     return $con->lastInsertId(); 
    } 
} 

OrderDetailRepository(LineItemsに)のための

注文リポジトリオーダー(すなわち、オーダー・エントリー+オーダー・ディテール・エントリー)。ここでは、2番目の挿入(Order Details)にエラーがある場合、Orderテーブルに挿入した作業をロールバックできるように、トランザクションを実装する方法を理解するのに役立つ必要があります。

class OrderService { 
    public static function createOrder($data) { 
     try { 
      $orderId = OrderRepository::insert($data); 
      $orderDetailId = OrderDetailRepository::insert($data); 

      // Commit transaction 
     } catch (\Exception $e) { 
      // Roll back transaction 
      return false; 
     } 
     return true; 
    } 
} 

私はこの質問を簡潔にしようとしたので、コード例は最小限に抑えられました。しかし、まだ私は冗談のために謝罪します。

おかげ

+0

簡潔なので、完全なコードを提供し、そのために謝罪する必要は良いではありません。 – Xorifelse

答えて

1

は単にOrderService->createOrder()方法

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 back transaction 
      $con->rollback(); 
      return false; 
     } 
     return true; 
    } 
} 

それともレベルを、それをバックに移動し、コールの周りにそれを行うことができ、この場合には、あなたは活動の流れを制御する場所の周りにトランザクションをラップOrderService->createOrder()

に方法は、次に

class OrderService { 
    public static function createOrder($data) { 
     $orderId = OrderRepository::insert($data); 
     $orderDetailId = OrderDetailRepository::insert($data); 
    } 
} 
に簡略化することができます

あなたの主な処理ループ

try { 
    $con = DBService::connect(); 
    $con->beginTransaction(); 

    $OrderService->createOrder($data); 

    $con->commit(); 

} catch (\Exception $e) { 
    // Roll back transaction 
    $con->rollback(); 
} 
関連する問題