@see https://www.websec-room.com/2015/11/17/2356
わかりやすくまとまっています(ㆁᴗㆁ✿)
<?php
  require_once("function.php");
 
  try{
 
    $dbh = new PDO(DSN, USERNAME, PASSWORD);
 
    // 静的プレースホルダを指定
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
 
    // エラー発生時に例外を投げる
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 
    //パラメータ
    $id = 1;
 
    //トランザクション処理を開始
    $dbh->beginTransaction();
 
    try {
      //プリペアドステートメント / ロック
      $stmt1 = $dbh->prepare("SELECT * FROM  USERS WHERE ID = ? FOR UPDATE");
      //$stmt1 = $dbh->prepare("SELECT * FROM  USERS WHERE ID = ? LOCK IN SHARE MODE”); //不整合が起きる
 
      $stmt1->bindParam(1, $id, PDO::PARAM_INT);
      $stmt1->execute();
 
 
      //プリペアドステートメント
      $stmt = $dbh->prepare("UPDATE USERS SET COUNT = COUNT + 1 WHERE ID = ?");
      $stmt->bindParam(1, $id, PDO::PARAM_INT);
      $stmt->execute();
 
      //コミット
      $dbh->commit();
 
    }catch(PDOException $e){
    
      //ロールバック
      $dbh->rollback();
 
      throw $e;
    }
 
  } catch(PDOException $e){
    echo $e->getMessage();
  }
 
?>
また、トランザクション分離レベルは以下のようになります(MySQL)。
ダーティーリード ファジーリード ファントムリード READ UNCOMMITED 起きる 起きる 起きる READ COMMITTED 起きない 起きる 起きる REPEATABLE READ 起きない 起きない 起きない SERIALIZABLE 起きない 起きない 起きない ※ REPEATABLE READ のファントムリードが起きないのは、MySQL の仕様
※ MySQL のデフォルトトランザクション分離レベルは REPEATABLE READ
※ ANSI/ISO SQL の既定では、REPEATABLE READ でファントムリードは起きる
InnoDB+REPEATABLE READの場合はファントムリードは起きない。
上記にはないけれど、ロールバック後のリトライ処理も必要
<?php
$retries = 3;
while ($retries > 0)
{
    try
    {
        $dbh = new PDO("mysql:host=localhost;dbname=blahblah", $user, $pass);
        // Do query, etc.
        $retries = 0;
    }
    catch (PDOException $e)
    {
        // Should probably check $e is a connection error, could be a query error!
        echo "Something went wrong, retrying...";
        $retries--;
        usleep(500); // Wait 0.5s between retries.
    }
}
ACID特性
@see http://d.hatena.ne.jp/fat47/20140212/1392171784
トランザクション処理に求められる4つの特性です。
原子性 (Atomicity)
トランザクションに含まれる手順が「すべて実行されるか」「すべてされないか」のどちらかになる性質。
一貫性 (Consistency)
どんな状況でもトランザクション前後でデータの整合性が矛盾なく保たれる性質。
分離性 (Isolation)
トランザクション実行中は、処理途中のデータは外部から隠蔽されて他の処理に影響を与えない性質。
永続性 (Durability)
トランザクションが完了したら、システムがクラッシュしてもデータが消失することがない性質。
ダーティリード、ファジーリード、ファントムリードなど解説もわかりやすい。
@see http://d.hatena.ne.jp/fat47/20140212/1392171784
分離レベルに関しての選択として、
InnoDB + REPEATABLE READ
でいいはず。













