5

所以我正在做的是有多个UPDATE查询,它更改表中的组名,tbl_groups然后更新tbl_users属于该组的所有用户,但如果用户更新查询失败,它会更新组,但我想同时更新一起或不一起使用,我正在使用 PHP 和 MySQL。

4

4 回答 4

2

听起来您需要做的就是使用事务。

必须使用 InnoDB 表才能使用事务(实际上,其他一些数据库引擎也有事务,但 InnoDB 最常见于 MySQL)。

在第一次更新之前发出“BEGIN TRANSACTION”查询。

如果任何查询失败,请发出“ROLLBACK”查询以撤消所有操作。

这真的很简单。

如果您决定要进行部分回滚(回到事务开始后的某个点),那么您可以使用“ROLLBACK TO SAVEPOINT savepoint_name”。您必须首先发出“SAVEPOINT savepoint_name”查询。

例如,在 PHP 中

mysql_query("BEGIN TRANSACTION");

$result1 = mysql_query("UPDATE `tbl_groups` SET `user_id` = 5 WHERE `group_id` = 3");
if($result1 === false) {
mysql_query("ROLLBACK");
}

mysql_query("SAVEPOINT savepoint1");

$result2 = mysql_query("UPDATE `tbl_users` SET `group_id` = 3 WHERE `user_id` = 5");

if($result === false) {
ROLLBACK TO SAVEPOINT savepoint1;
}
// COMMIT saves the changes to the db, making them visible to other sessions
// if the ROLLBACK TO SAVEPOINT statement executed, then only changes up to that SAVEPOINT will be saved
// if no ROLLBACK statements were executed, then all changes will be saved (assuming no MySQL errors that cause implicit ROLLBACK)
mysql_query('COMMIT');
于 2013-01-12T09:59:01.507 回答
0

使用具有最佳隔离级别的事务

我更喜欢“可重复读取”(在您提交事务之前,您无法查看其他数据和虎钳)总是好的,它是 innodb 存储引擎的默认设置

如果您不使用 innodb 则更改隔离级别

设置全球 tx_isolation='REPEATABLE-READ'; 或者

设置会话 tx_isolation='REPEATABLE-READ';

其余细节由@Buttle Butkus 提供

于 2013-01-12T10:43:57.860 回答
0

将 tbl_groups 和 tbl_users 之间的关系设置为ON DELETE CASCADE。然后只需更新 tbl_groups,更改将级联到 tbl_users 中的相关记录。如果您必须经常像这样更新您的父键,那么您可能会考虑使用代理键。

于 2013-01-12T13:29:51.723 回答
0

以下示例基于面向对象的样式,请确保您的所需数据库表类型为 InnoDB,因为它支持事务语句

在这里,我只想根据 id 删除多条记录

$this->link_id->autocommit(FALSE); 

// 上面的语句通过禁用自动提交来启动事务,其中 link_id 是指您的 MySQLi 数据库连接

        for($i=1; $i<=5; $i++){     

            $tSql = "DELETE FROM your_table" 
                     . " WHERE id=" . $i;

            $rs = $this->link_id->query($tSql);// execute the query

            if($this->link_id->affected_rows == -1) // check if it fails
            {   
               $_SESSION["error"] = "Sorry ! cant be deleted ! ";           
                $this->link_id->rollback(); // rollback the transaction
                break; // break the loop

            }           

        }



//check if there is some error or not, if no error then commit the transaction
        if(empty($_SESSION["error"])){          
            $this->link_id->commit();
        }
于 2016-08-25T06:25:36.987 回答