example - transacciones mysql php ejemplo
¿Transacciones PHP PDO? (1)
Tengo una página de registro y básicamente necesito datos insertados en 4 tablas. Soy nuevo en PDO y estoy confundido por algo.
Básicamente, si alguno de los insertos falla, no quiero agregar nada a la base de datos, eso parece bastante simple.
Mi confusión es que primero necesito insertar el nombre de usuario, el correo electrónico, la contraseña, etc. en mi tabla de users
para poder obtener (no estoy seguro cómo) usando PDO que el uid MySQL le ha dado a mi usuario (auto incrementado por mysql). Necesito el usuario uid MySQL le dio a mi usuario las otras tablas, ya que las otras tablas necesitan el uid para que todo esté vinculado correctamente. Mis tablas son InnoDB y tengo claves externas que van desde users_profiles (user_uid), users_status (user_uid), users_roles (user_uid) hasta users.user_uid para que estén todos vinculados entre sí.
Pero al mismo tiempo quiero asegurarme de que si, por ejemplo, después de insertar datos en la tabla de users
(para que pueda obtener el usuario que MySQL le dio al usuario), si alguno de los otros inserts falla, elimina los datos que se insertaron en el tabla de users
.
Creo que es mejor que muestre mi código; He comentado el código y lo he explicado en el código, lo que puede facilitar su comprensión.
// Begin our transaction, we need to insert data into 4 tables:
// users, users_status, users_roles, users_profiles
// connect to database
$dbh = sql_con();
// begin transaction
$dbh->beginTransaction();
try {
// this query inserts data into the `users` table
$stmt = $dbh->prepare(''
INSERT INTO `users`
(users_status, user_login, user_pass, user_email, user_registered)
VALUES
(?, ?, ?, ?, NOW())'');
$stmt->bindParam(1, $userstatus, PDO::PARAM_STR);
$stmt->bindParam(2, $username, PDO::PARAM_STR);
$stmt->bindParam(3, $HashedPassword, PDO::PARAM_STR);
$stmt->bindParam(4, $email, PDO::PARAM_STR);
$stmt->execute();
// get user_uid from insert for use in other tables below
$lastInsertID = $dbh->lastInsertId();
// this query inserts data into the `users_status` table
$stmt = $dbh->prepare(''
INSERT INTO `users_status`
(user_uid, user_activation_key)
VALUES
(?, ?)'');
$stmt->bindParam(1, $lastInsertID, PDO::PARAM_STR);
$stmt->bindParam(2, $activationkey, PDO::PARAM_STR);
$stmt->execute();
// this query inserts data into the `users_roles` table
$stmt = $dbh->prepare(''
INSERT INTO `users_roles`
(user_uid, user_role)
VALUES
(?, ?)'');
$stmt->bindParam(1, $lastInsertID, PDO::PARAM_STR);
$stmt->bindParam(2, SUBSCRIBER_ROLE, PDO::PARAM_STR);
$stmt->execute();
// this query inserts data into the `users_profiles` table
$stmt = $dbh->prepare(''
INSERT INTO `users_profiles`
(user_uid)
VALUES
(?)'');
$stmt->bindParam(1, $lastInsertID, PDO::PARAM_STR);
$stmt->execute();
// commit transaction
$dbh->commit();
} // any errors from the above database queries will be catched
catch (PDOException $e) {
// roll back transaction
$dbh->rollback();
// log any errors to file
ExceptionErrorHandler($e);
require_once($footer_inc);
exit;
}
Soy nuevo en PDO y es posible que haya errores o problemas que todavía no he notado porque no puedo probarlos hasta que descubra mi problema.
1) Necesito saber cómo puedo insertar los datos de los usuarios en la tabla de usuarios primero para que pueda obtener el uid que MySQL le dio a mi usuario
2) Luego obtenga el uid como lo necesito para las otras tablas
3) Pero al mismo tiempo, si una consulta falla por cualquier motivo después de insertar en la tabla de usuarios, también se eliminan los datos de la tabla de usuarios.
ACTUALIZAR:
Actualicé el código anterior para reflejar los cambios que me ofrecieron miembros útiles.
Esta función devuelve la clave principal del registro insertado: PDO::lastInsertId Lo necesitará para el parámetro NEED_USERS_UID_FOR_HERE
. Úselo justo después de la instrucción INSERT.
Desde que comenzó una transacción, los datos no se insertarán en ninguna tabla si se produce algún error siempre que use el motor InnoDB para sus tablas MySQL (MyISAM no admite transacciones).