回答編集履歴

1

追記

2017/10/12 10:47

投稿

miyahan
miyahan

スコア3095

test CHANGED
@@ -20,8 +20,96 @@
20
20
 
21
21
 
22
22
 
23
- ですが、現代のMySQLにおいてWebアプリケーションの一般処理でテーブルロックを使うことはまずありません。またテーブルをロックしても `dat_sales` にINSERTした直後にアプリやDBの処理が止まって仕舞った場合、注文番号はあるが何も商品を買っていないという不整合が容易に発生します。
23
+ ですが、現代のPHP+MySQLにおいてWebアプリケーションの一般処理でテーブルロックすることはまずありません。またテーブルをロックしたとしても `dat_sales` にINSERTした直後にアプリやDBの処理が止まって仕舞った場合、"注文番号はあるが何も商品を買っていない" という不整合が容易に発生します。
24
24
 
25
25
 
26
26
 
27
- そのような不整合を防ぐには**トランザクション**という機能を使います。データベースを使う上で極めて重要な機能・概念ですので、ぜひ勉強して取り入れて下さい。
27
+ そのような不整合を防ぐには**トランザクション**という機能を使います。トランザクションを使うことで完全な失敗(DBに何も記録しない)か完全な成功(DBに全てのデータが漏れなく記録される)のどちらかになり、**中途半端に更新されてDBの情報が破綻するといったトラブルを防ぐ**ことができます。データベースを使う上で極めて重要な機能・概念ですので、ぜひ勉強してマスターして下さい。
28
+
29
+
30
+
31
+ [PHP: トランザクションおよび自動コミット - Manual](http://php.net/manual/ja/pdo.transactions.php)
32
+
33
+
34
+
35
+ ---
36
+
37
+
38
+
39
+ あと細かいところですがいくつか:
40
+
41
+
42
+
43
+ DB の最後に挿入された行のIDは、PDOの `lastInsertId()` を使って一発で取得できます。
44
+
45
+
46
+
47
+ ```php
48
+
49
+ // before
50
+
51
+ $sql = 'select last_insert_id()';
52
+
53
+ $product = $pdo->prepare($sql);
54
+
55
+ $product->execute();
56
+
57
+ $rec = $product->fetch(PDO::FETCH_ASSOC);
58
+
59
+ $lastcode = $rec['last_insert_id()']
60
+
61
+
62
+
63
+ // after
64
+
65
+ $lastcode = $pdo->lastInsertId();
66
+
67
+ ```
68
+
69
+
70
+
71
+ 同じ文法のプリペアドステートメントは使い回せるのでループの外に出しましょう。データベースの負荷が減り、パフォーマンスもあがります。
72
+
73
+
74
+
75
+ ```php
76
+
77
+ // Before
78
+
79
+ for($i=0; $i<count($cart); $i++){
80
+
81
+ $sql = 'insert into dat_sales_product(code_sales,code_product,price,quantity)values(?,?,?,?)';
82
+
83
+ $product = $pdo->prepare($sql);
84
+
85
+ $product->bindValue(1, $lastcode);
86
+
87
+ $product->bindValue(2, $cart[$i]);
88
+
89
+ //...//
90
+
91
+ $product->execute();
92
+
93
+ }
94
+
95
+
96
+
97
+ // After
98
+
99
+ $sql = 'insert into dat_sales_product(code_sales,code_product,price,quantity)values(?,?,?,?)';
100
+
101
+ $product = $pdo->prepare($sql);
102
+
103
+ for($i=0; $i<count($cart); $i++){
104
+
105
+ $product->bindValue(1, $lastcode);
106
+
107
+ $product->bindValue(2, $cart[$i]);
108
+
109
+ //...//
110
+
111
+ $product->execute();
112
+
113
+ }
114
+
115
+ ```