我有两张桌子:
user_tb.username user_tb.point
review_tb.username review_tb.review
我正在用PHP编码(CodeIgniter)。所以我试图通过用户提交的评论将数据插入到review_tb中,如果成功,我会给用户一些积分。
这看起来像一个非常简单的过程。我们将首先使用用户名将评论插入review_tb并使用PHP检查执行的查询是否有任何问题,如果成功,我们将继续更新user_tb中的点。
是的,但问题来了。如果插入到review_tb是成功但插入到user_tb的第二个查询不成功,我们可以“撤消”review_tb查询或“恢复”我们对review_tb所做的更改。
有点像“全有或全无”。
这样做的目的是同步数据库中的所有数据,在现实生活中,我们将管理更多表的数据库,并将更多数据插入到彼此依赖的每个表中。
请对如何在PHP或CodeIgniter中执行此操作或仅使用MySql查询提供一些启示。
答案 0 :(得分:3)
如果您想要SQL操作的“全有或全无”行为,那么您正在寻找transactions;这是MySQL手册中的相关页面:12.4.1. START TRANSACTION, COMMIT, and ROLLBACK Syntax。
维基百科以这种方式描述:
数据库事务包括a 在一个单位内完成的工作单位 数据库管理系统(或 类似的系统)对数据库, 并且连贯可靠地进行治疗 独立于其他交易的方式。 数据库环境中的事务 有两个主要目的:
- 提供可靠的工作单元,以便从中正确恢复 失败并保留数据库 即使在系统的情况下也是一致的 执行停止时失败 (完全或部分)和许多 对数据库的操作仍然存在 尚未完成,状态不明。
- 在访问数据库的程序之间提供隔离 同时。没有隔离的 程序的结果通常是 错误的。
醇>
基本上:
有一个关于transactions and CodeIgniter here的手册页。
请注意,使用MySQL,并不是每个引擎都支持事务;在两个最常用的引擎之间,MyISAM不支持事务,而InnoDB支持它们。
答案 1 :(得分:0)
你不能使用交易吗?如果你在同一个事务中做了两个插入,那么要么都成功要么两者都没有。
尝试类似
的内容BEGIN;
INSERT INTO review_tb(username, review) VALUES(x, y);
INSERT INTO user_tb(username, point) VALUES(x, y);
COMMIT;
请注意,您需要使用支持事务的数据库引擎(例如InnoDB)。
答案 2 :(得分:0)
如果您有InnoDB支持,请使用它,但如果不可能,您可以使用类似以下的代码:
$result=mysql_query("INSERT INTO ...");
if(!$result) return false;
$result=mysql_query("INSERT INTO somewhereelse");
if(!$result) {
mysql_query("DELETE FROM ...");
return false;
}
return true;
此清理可能仍会失败,但只要插入查询因重复或约束而失败,它就可以正常工作。对于意外终止,唯一的方法是使用事务。