MySQL

MySQLのトランザクションとか分離レベルメモ

 

@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

でいいはず。

 

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)