だから私がやっていることは、テーブルUPDATE
内のグループ名を変更し、そのグループに属するすべてのユーザーを更新する複数のクエリを持っていることですが、ユーザー更新クエリが失敗した場合、グループを更新しますが、両方を更新したいです一緒にまたはなしで、PHP と MySQL を使用しています。tbl_groups
tbl_users
4 に答える
必要なのはトランザクションを使用することだけのようです。
トランザクションを使用するには InnoDB テーブルを使用する必要があります (実際、他の DB エンジンにはトランザクションがありますが、MySQL では InnoDB が最も一般的です)。
最初の更新の前に「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');
次の例はオブジェクト指向スタイルに基づいています。トランザクションステートメントをサポートしているため、必要なデータベーステーブルのタイプが 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();
}
最高の分離レベルでトランザクションを使用する
私は「反復可能な読み取り」(トランザクションをコミットするまで、他のデータを表示したり、その逆を表示したりすることはできません)が常に適切であり、innodbストレージエンジンのデフォルトです。
innodbを使用していない場合は、分離レベルを変更してください
SET GLOBAL tx_isolation='REPEATABLE-READ'; また
SET SESSION tx_isolation='REPEATABLE-READ';
残りの詳細は@Buttle Butkusによって提供されます
tbl_groups と tbl_users の関係を に設定しON DELETE CASCADE
ます。次に、tbl_groups を更新するだけで、変更が tbl_users の関連レコードにカスケードされます。このように親キーを頻繁に更新する必要がある場合は、代わりに代理キーを使用することを検討できます。