Hi everyone
I need your help, I can’t figure out why I’m getting errors here. I’ve used transactions, and prepared statements, and last_insert_id() before, but when I combine them all, I get errors. If you can take a look at this:
<?php
// Connection details above
// Create connection for prepared statements
$db = new mysqli($dbHost, $dbUser, $dbPass, $dbName);
try {
// First of all, begin a transaction
mysqli_begin_transaction($conn);
mysqli_autocommit($conn, FALSE);
// A set of queries; if one fails, an exception should be thrown
$result = mysqli_query($conn, " INSERT INTO vendors (v_status) VALUES (0) "); //automatically gives v_ref an auto_incremented value
if (!$result) {
echo "1st query unsuccessful";
mysqli_rollback($conn);
}
//this statements inserts the table 'vendor's primary key into v_i_ref here:
$stmt = $db->prepare(" INSERT INTO vendor_information (v_i_ref, v_i_email, v_i_username, v_i_pass, v_i_province, v_i_town, v_i_agreement) VALUES (LAST_INSERT_ID(), ?, ?, ?, ?, ?, 1) ");
$stmt->bind_param('sssss', $email, $username, $hashed_password, $province, $city);
// $stmt->execute();
if ($stmt->execute()) {
//statement executed successfully
} else {
echo "2nd query unsuccessful";
echo $stmt->error;
mysqli_rollback($conn);
}
$result = mysqli_query($conn, " INSERT INTO user_reputation (u_r_v_ref) SELECT MAX(v_ref) FROM vendors "); //this causes the transaction to exceed 50 seconds! thereby failing the transaction!
if (!$result) {
echo "3rd query unsuccessful";
mysqli_rollback($conn);
}
$stmt = $db->prepare(" INSERT INTO ip_addresses (i_a_user_ref, i_a_address) VALUES ((SELECT MAX(v_ref) FROM vendors), ?) ");
$stmt->bind_param('s', $client_connection);
if (!$stmt->execute()) {
echo "4th query unsuccessful";
mysqli_rollback($conn);
}
$stmt = $db->prepare(" INSERT INTO user_agents (u_a_v_ref, u_a_user_agent) VALUES ( (SELECT MAX(v_ref) FROM vendors), ?) ");
$stmt->bind_param('s', $client_useragent);
if (!$stmt->execute()) {
echo "5th query unsuccessful";
mysqli_rollback($conn);
}
$result = mysqli_query($conn, " INSERT INTO pedlarcash_accounts (p_a_v_ref) SELECT MAX(v_ref) FROM vendors "); /*inserts vendor reference here*/
if (!$result) {
echo "6th query unsuccessful";
mysqli_rollback($conn);
}
$result = mysqli_query($conn, " INSERT INTO pedlarcash_closing_balances(p_c_b_account) SELECT MAX(p_a_account_number) FROM pedlarcash_accounts "); /*inserts account number here*/
if (!$result) {
echo "7th query unsuccessful";
mysqli_rollback($conn);
}
// If we arrive here, it means that no exception was thrown
// i.e. no query has failed, and we can commit the transaction
mysqli_commit($conn);
} catch (Exception $e) {
// An exception has been thrown
// We must rollback the transaction
mysqli_rollback($conn);
//Check if rows have been affected
if (mysqli_affected_rows($conn) == 0) {
echo "No rows have been affected!";
} else {
echo "Successfully completed the transaction!";
}
}
If I use LAST_INSERT_ID()
then a foreign key constraint fails, and if I use (SELECT MAX(v_ref) FROM vendors)
then the code takes so long to execute that it fails the transaction with “Lock wait timeout exceeded; try restarting transaction”.
How is a transaction like this done?
Basically I have about 7 tables so that each time a user registers, his information is inserted into the various tables by using a transaction (it should never, ever, insert into half the tables only - therefore I must use a transaction).
And the way to link the user on every table is by using their ID. The id is a primary key in ‘vendors’ and a foreign key in every other table.
Can you see any apparent issue with the way the transaction is being executed? Any slight tip would be much appreciated…