0

我正在开发一个基于 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 添加内容”。我猜第一条和第二条语句会被执行,其余的不会?

确保不会发生这种情况的最佳方法是什么,因为它可能会弄乱其他表的键等。我可能对解释有点模糊,但我希望有人能理解我的观点。

我读过“存储过程和触发器中的回滚和提交”,但我不确定我是否理解正确..

提前致谢。

4

2 回答 2

1

如果它是 InnoDB,那么您应该使用事务来进行这种插入。有关更多信息,请参阅:

于 2012-10-10T10:28:39.010 回答
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
于 2012-10-10T10:43:46.797 回答