I can't get this to work the way I want. It's a really simple job actually:
Register a webshop order in the "orders" table. This table contains general information about the order, like who made the order, date and stuff like that. When this is done I use the auto_incremented ID ($oid) for step 2:
Loop: Register each product ordered in the "orderrow" table.
This is where I whant to use transactions. Either step 1 and the loop in step 2 all works out, or none should be registered. This is how I tried it:
- Connect
- SEt autocommit FALSE
- do step 1
- check mysqli->sqlstate, if not "00000" then rollback
- Step 2 width sqlstate checks for each loop
However it registers step 1 immediately, it does not wait for my commit command. I use phpmyadmin to look at the database and I can see the record there even if I die() the script before it is finished. Is that normal?
I'm not sure how the transaction log really works. I thought all transactions where written to the log, and thereby not visible from e.g. phpmyadmin, and then when the commit() was run it was transferred to the database and cleard from the transaction table. Wrong?
Here's a code example from my DBLayer class (autocommit already set to FALSE via constructor):
public function saveOrder(order $order)
{
$uid = $order->getUID();
$timestamp = $order->getDate();
$stmt = DBLayer::$mysqli->prepare("INSERT INTO orders SET uid = ?, date = ?, status = 'new'");
$stmt->bind_param("ii", $uid, $timestamp);
$stmt->execute();
$oid = $stmt->insert_id;
$stmt->close();
if(DBLayer::$mysqli->sqlstate != "00000")
{
# error handling, rollback, then return errorcode
}
# Save orderrows
$orderrows = $order->getOrderRows();
for($i = 0; $i < count($orderrows); $i++)
{
$price = $orderrows[$i]->getPriceIncVAT();
$count = $orderrows[$i]->getCount();
$pid = $orderrows[$i]->getPID();
$stmt = DBLayer::$mysqli->prepare("INSERT INTO orders_row SET oid = ?, pid = ?, count = ?, price = ?");
$stmt->bind_param("iiid", $oid, $pid, $count, $price);
$stmt->execute();
$stmt->close();
# Same error check here then...
}
return $oid;
}
I've make an error in the qsl query in the loop (step 2) to check, and step 1 was not rolled back.