我正在开发基于php / MySQLi的网站。我有一个问题,如果由于某种原因页面在执行复杂过程的过程中崩溃会发生什么。
示例:
if (get_message_call)
{
add something to table 1
add something to table 2
add something to table 3 ( based on some values inserted into table2 )
add something to table 4
etc...
}
我使用PHPmyAdmin(InnoDB)构建了数据库。我没有分配任何关系,因为主/外键没有像理论上那样工作(也许我错了)。
我主要担心的是,如果由于某种原因声明中止(页面崩溃,连接松动等),请执行“向table3添加内容”。我猜第一个和第二个语句将被执行,其余的不会?
确保这种情况不可能发生的最佳方法是什么,因为它可能会弄乱其他表格的键等...我可能会对explenation有点模糊,但我希望有人理解我的观点。
我读过“存储过程和触发器中的回滚和提交”,但我不确定我是否理解它..
提前致谢。
答案 0 :(得分:1)
如果它是InnoDB,那么你应该使用这种插入的事务。有关详细信息,请参阅:
答案 1 :(得分:0)
这是您应该使用数据库事务的情况。当您必须更新多个表,并且更新取决于以前的更新时,最安全的做法是将代码放入数据库的存储过程中。存储过程可以启动一个事务,只有当数据正确完成时才会将数据提交到数据库(这意味着如果你写入一个表,写入第二个表,但第三个写入失败,第一个和第二个写入是也回滚了。)
这是一个示例 - 存储过程需要3个输入参数,返回2个输出值并更新3个表。如果有任何错误,则事务回滚。 (注意这只是一个例子,可能存在轻微的语法错误)
CREATE DEFINER=`root`@`localhost` PROCEDURE `doSomething`(
IN input1 INT,
IN input2 VARCHAR(255),
IN input3 VARCHAR(100),
OUT output1 INT,
OUT output2 INT
)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; END;
DECLARE EXIT HANDLER FOR SQLWARNING BEGIN ROLLBACK; END;
DECLARE EXIT HANDLER FOR NOT FOUND BEGIN ROLLBACK; END;
START TRANSACTION;
INSERT INTO table1 (column1, column2, column3) VALUES (input1, input2, NOW());
SET @new_row_id = LAST_INSERT_ID();
INSERT INTO table2 (column1, colum2) VALUES (@new_row_id, input3);
SET @other_new_row_id = LAST_INSERT_ID();
UPDATE table3 SET mycolumn = @other_new_row_id WHERE id = @new_row_id;
COMMIT;
SET output1 = @new_row_id;
SET output2 = @other_new_row_id;
END