ある業務テーブルのプライマリキーを番号体系にしていて、当該テーブルへのレコード挿入時は逐次、番号管理用の別テーブルから番号を採取(1行しかありません)して これを用いる仕様で考えています。
自分が考えたのは以下コーディングです。
新たに番号管理テーブルで番号を採取する(一つ繰り上げる)処理と、今しがた採取した番号を他テーブルに用いる処理が分かれてしまう以上は、他ユーザが同じ操作をしている場合 相応のリスクが伴うのでは??と危惧していますが 間違いありませんか??
一つのトランザクションにしたところで(以下は一つのトランザクションの認識です...)、次のSELECT文で必ず自分が採取した番号をひいてくるとは限らない、この2ステップの間レコードロックをするようなことをしなければならない、と解釈しています。
これは間違いありませんか?
この2ステップ(星印で囲んだ部分)を一まとまりにしてレコードロックするような記述を、PHPではできるのでしょうか?
PHP
1function initial($BIID) { 2 try { 3 4 //DBへ接続 【php_etc/dbconnect.phpに接続先は書いてあります】 5 $err_stage = "err#051"; 6 $db = new ms0connect(); 7 $conn = $db->dbconnect(); 8 $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 9 $conn->beginTransaction(); 10 11 //☆★☆★ 12 $err_stage = "err#052"; 13 $SQL = "UPDATE ATOZ_FINALSEQ SET FINALSEQ=FINALSEQ + 1 WHERE SYSTEMTYPE='".$BIID."'"; 14 $conn->exec($SQL); 15 16 $err_stage = "err#053"; 17 $SQL = "SELECT TOP 1 FINALSEQ FROM ATOZ_FINALSEQ WHERE SYSTEMTYPE='".$BIID."'"; 18 $stmt=$conn->prepare($SQL); 19 $stmt->execute(); 20 //☆★☆★ 21 22 $row = null; 23 $row = $stmt->fetch(PDO::FETCH_ASSOC); 24 if ($row == null) { 25 $err_stage = "err#054"; 26 throw new Exception(); 27 } else { 28 $appno = substr(strval(1000000000 + $row["FINALSEQ"]),-9); 29 $appno = $BIID.$appno; 30 } 31 32 $err_stage = "err#055"; 33 $SQL = "INSERT ATOZ_PLNROUT 34 SELECT A.BIID, A.ORNO, A.FIN, '".$appno."' AS WID, A.STID, B.STNAME, A.USEDPT, NULL AS ACTOP FROM V_ATOZ_BIROUT A LEFT OUTER JOIN 35 (SELECT STID, MAX(STNAME) AS STNAME FROM V_ATOZ_STAGE GROUP BY STID) B 36 ON B.STID=A.STID WHERE A.BIID='".$BIID."'"; 37 $stmt=$conn->prepare($SQL); 38 $stmt->execute(); 39 40 41 $err_stage = "err#056"; 42 $SQL = "INSERT ATOZ_PLNSTAGE 43 SELECT '".$BIID."' AS BIID, '".$appno."' AS WID, A.STID, A.DPTID, A.STNAME, A.USERID, A.SUB, A.USEEXTCON, A.EXTCON FROM V_ATOZ_STAGE A 44 WHERE A.STID IN (SELECT DISTINCT STID FROM V_ATOZ_BIROUT WHERE BIID='".$BIID."')"; 45 $stmt=$conn->prepare($SQL); 46 $stmt->execute(); 47 48 $conn->commit(); 49 $err_stage = null; 50 51 } catch (PDOException $e) { 52 error_log("### SQL Serverデータ取得失敗 ⇒".$SQL."###".$e->getMessage(),0); 53 } catch (Exception $e) { 54 error_log("### SQL Serverデータ取得失敗 ⇒".$SQL."###".$e->getMessage(),0); 55 } 56 $conn = null; 57 return $err_stage; 58}
回答2件
あなたの回答
tips
プレビュー