Bak*_*yor 37 php mysqli transactions
据我所知,事务一旦调用$mysqli->autocommit(FALSE);
语句就开始,并在调用$mysqli->commit();
命令后结束,如下例所示.
<?php
//Start transaction
$mysqli->autocommit(FALSE);
$mysqli->query('UPDATE `table` SET `col`=2');
$mysqli->query('UPDATE `table1` SET `col1`=3;');
$mysqli->commit();
//End transaction
//Executing other queries without transaction control
$mysqli->query("Select * from table1");
$mysqli->query("Update table1 set col1=2");
//End of executing other queries without transaction control
//Start transaction
$mysqli->autocommit(FALSE);
$mysqli->query('UPDATE `table` SET `col`=2');
$mysqli->query('UPDATE `table1` SET `col1`=3;');
$mysqli->commit();
//End transaction
?>
Run Code Online (Sandbox Code Playgroud)
我理解正确吗?如果没有,请你纠正我,因为这实际上是我第一次在现实生活中使用交易.
谢谢.
小智 30
除了丢弃表外,j0k主要是正确的.
使用 - > commit()不会打开自动提交
相反,DROP TABLE是一个DDL查询,并且DDL查询总是被隐式提交,并将提交所有以前未提交的工作.
因此,如果您未提交工作,则DDL查询将强制执行此提交.
j0k*_*j0k 26
那么根据php doc,你是对的.
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$mysqli->query("CREATE TABLE Language LIKE CountryLanguage");
/* set autocommit to off */
$mysqli->autocommit(FALSE);
/* Insert some values */
$mysqli->query("INSERT INTO Language VALUES ('DEU', 'Bavarian', 'F', 11.2)");
$mysqli->query("INSERT INTO Language VALUES ('DEU', 'Swabian', 'F', 9.4)");
/* commit transaction */
$mysqli->commit();
/* drop table */
$mysqli->query("DROP TABLE Language");
/* close connection */
$mysqli->close();
?>
Run Code Online (Sandbox Code Playgroud)
在上面的例子中:
CREATE TABLE
是自动提交,因为它是默认的行为.INSERT INTO
没有自动致力于因为autocommit(FALSE)
DROP TABLE
是自动提交,因为autocommit(FALSE)
被重置了通过->commit();
.Dha*_*man 13
为了使事务正常运行,您应该启用异常错误报告。否则mysqli不会报错,事务也不会正确执行。或者,您可以手动检查每个查询,但不建议这样做。要与 mysqli 正确连接,请使用以下 3 行:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'user', 'pass', 'dbname');
$mysqli->set_charset('utf8mb4'); // always set the charset
Run Code Online (Sandbox Code Playgroud)
使用 mysqli 创建事务有两种可能的方法。默认情况下,所有查询/语句在执行后立即提交。您可以关闭自动提交或使用一次性事务。
在以下情况下,事务将提交到数据库:
commit
如果关闭自动提交,您可以决定何时提交,但调用commit()
不会重新打开自动提交。
//Start transaction
$mysqli->autocommit(false);
$mysqli->query('INSERT INTO director(name) VALUE("Steven Spielberg")');
$directorId = $mysqli->insert_id;
$movieTitle = 'Jurassic Park';
$stmt = $mysqli->prepare('INSERT INTO movie(title, directorId) VALUE(?,?)');
$stmt->bind_param('ss', $movieTitle, $directorId);
$stmt->execute();
$mysqli->commit();
// Changes are committed, but autocommit is not switched back on
// Following queries are still transactional. They will not be committed unless you call commit or switch autocommit back on
$mysqli->query('INSERT INTO director(name) VALUE("James Cameron")');
$directorId = $mysqli->insert_id;
$movieTitle = 'Titanic';
$stmt = $mysqli->prepare('INSERT INTO movie(title, directorId) VALUE(?,?)');
$stmt->bind_param('ss', $movieTitle, $directorId);
$stmt->execute();
$mysqli->autocommit(true);
// All queries are committed and everything that follows will be immediately committed.
Run Code Online (Sandbox Code Playgroud)
您可以使用 启动一次性事务begin_transaction()
。autocommit=false
当你打电话commit()
结束交易而不开始新的交易时,这不会设置。
//Start transaction
$mysqli->begin_transaction();
$mysqli->query('INSERT INTO director(name) VALUE("Steven Spielberg")');
$directorId = $mysqli->insert_id;
$movieTitle = 'Jurassic Park';
$stmt = $mysqli->prepare('INSERT INTO movie(title, directorId) VALUE(?,?)');
$stmt->bind_param('ss', $movieTitle, $directorId);
$stmt->execute();
$mysqli->commit();
// Changes are committed and the transaction has ended
// Following queries will be committed one by one as soon as they are peformed.
$mysqli->query('INSERT INTO director(name) VALUE("James Cameron")');
$directorId = $mysqli->insert_id;
$movieTitle = 'Titanic';
$stmt = $mysqli->prepare('INSERT INTO movie(title, directorId) VALUE(?,?)');
$stmt->bind_param('ss', $movieTitle, $directorId);
$stmt->execute();
Run Code Online (Sandbox Code Playgroud)
某些 SQL 语句会触发显式提交,但不会影响 的值autocommit
。
//Start transaction
$mysqli->autocommit(false);
$mysqli->query('INSERT INTO director(name) VALUE("Steven Spielberg")');
$directorId = $mysqli->insert_id;
$movieTitle = 'Jurassic Park';
$stmt = $mysqli->prepare('INSERT INTO movie(title, directorId) VALUE(?,?)');
$stmt->bind_param('ss', $movieTitle, $directorId);
$stmt->execute();
// The following will call commit but it will not set autocommit=true
$mysqli->query('TRUNCATE TABLE movie_genre');
// if you want to switch autocommit back on, you have to call:
$mysqli->autocommit(true);
Run Code Online (Sandbox Code Playgroud)
如果发生异常,PHP 将结束脚本的执行并且代码永远不会到达commit
语句。但是,在某些情况下,您可能希望显式回滚事务,例如避免在代码中的其他地方意外调用 commit。
以下是此类交易的示例。第二个查询试图插入一个不存在的表,这意味着 mysqli 将抛出异常。我们没有让 PHP 脚本死掉,而是捕获异常并回滚事务。该值4
永远不会插入到数据库中,因为两个查询都已回滚。
try {
// Start transaction
$mysqli->begin_transaction();
$mysqli->query('INSERT INTO some_table(col2) VALUE(4)');
$mysqli->query('INSERT INTO does_not_exist(col2) VALUE(4)');
// Commit changes
$mysqli->commit();
} catch (\Throwable $e) {
// Something went wrong. Rollback
$mysqli->rollback();
// Rethrow the exception so that PHP does not continue with the execution and the error can be logged in the error_log
throw $e;
}
Run Code Online (Sandbox Code Playgroud)
sbr*_*bot 12
准备SQL语句ONCE,然后执行多次:
<?php
$Mysqli = new mysqli("host","user","pass","base");
// check connection
if(mysqli_connect_errno())
{
printf("Connect failed: %s\n",mysqli_connect_error());
exit();
}
// some data for db insertion
$countries=['Austria','Belgia','Croatia','Denmark','Estonia'];
// explicitly begin DB transaction
$Mysqli->begin_transaction();
// prepare statement (for multiple inserts) only once
$stmt=$Mysqli->prepare("INSERT INTO table(column) VALUES(?)");
// bind (by reference) prepared statement with variable $country
$stmt->bind_param('s',$country);
// load value from array into referenced variable $country
foreach($countries as $country)
{
//execute prep stat more times with new values
//$country is binded (referenced) by statement
//each execute will get new $country value
if(!$stmt->execute())
{
// rollback if prep stat execution fails
$Mysqli->rollback();
// exit or throw an exception
exit();
}
}
// close prepared statement
$stmt->close();
// commit transaction
$Mysqli->commit();
// close connection
$Mysqli->close();
?>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
48228 次 |
最近记录: |