本文目录导读:

在PHP项目中实现数据库事务,主要取决于你使用的数据库扩展或ORM框架,以下是几种常见的实现方式:
使用 PDO (PHP Data Objects)
基本事务处理
try {
// 创建PDO连接
$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 开始事务
$pdo->beginTransaction();
// 执行多个数据库操作
$pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
$pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
// 提交事务
$pdo->commit();
echo "事务执行成功!";
} catch (Exception $e) {
// 回滚事务
$pdo->rollBack();
echo "事务执行失败:" . $e->getMessage();
}
使用预处理语句的事务
try {
$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->beginTransaction();
// 预处理语句
$stmt1 = $pdo->prepare("UPDATE accounts SET balance = balance - ? WHERE id = ?");
$stmt2 = $pdo->prepare("UPDATE accounts SET balance = balance + ? WHERE id = ?");
$stmt1->execute([100, 1]);
$stmt2->execute([100, 2]);
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
echo "错误:" . $e->getMessage();
}
使用 MySQLi (MySQL Improved)
面向对象方式
// 创建连接
$mysqli = new mysqli('localhost', 'username', 'password', 'test');
// 检查连接
if ($mysqli->connect_error) {
die("连接失败: " . $mysqli->connect_error);
}
// 开始事务
$mysqli->begin_transaction();
try {
// 执行操作
$mysqli->query("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
$mysqli->query("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
// 提交事务
$mysqli->commit();
echo "事务执行成功";
} catch (Exception $e) {
// 回滚事务
$mysqli->rollback();
echo "事务执行失败:" . $e->getMessage();
}
$mysqli->close();
过程化方式
$link = mysqli_connect('localhost', 'username', 'password', 'test');
if (!$link) {
die('连接失败: ' . mysqli_connect_error());
}
// 关闭自动提交
mysqli_autocommit($link, false);
$success = true;
if (!mysqli_query($link, "UPDATE accounts SET balance = balance - 100 WHERE id = 1")) {
$success = false;
}
if (!mysqli_query($link, "UPDATE accounts SET balance = balance + 100 WHERE id = 2")) {
$success = false;
}
if ($success) {
mysqli_commit($link);
echo "事务执行成功";
} else {
mysqli_rollback($link);
echo "事务执行失败";
}
mysqli_close($link);
使用 Laravel 框架
Eloquent ORM 事务
use Illuminate\Support\Facades\DB;
use App\Models\Account;
// 方法1:使用闭包
DB::transaction(function () {
Account::where('id', 1)->decrement('balance', 100);
Account::where('id', 2)->increment('balance', 100);
});
// 方法2:手动控制
try {
DB::beginTransaction();
Account::where('id', 1)->decrement('balance', 100);
Account::where('id', 2)->increment('balance', 100);
DB::commit();
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
事务锁处理
DB::transaction(function () {
// 悲观锁 (行锁)
$account1 = Account::where('id', 1)->lockForUpdate()->first();
$account2 = Account::where('id', 2)->lockForUpdate()->first();
$account1->balance -= 100;
$account2->balance += 100;
$account1->save();
$account2->save();
});
使用 ThinkPHP 框架
use think\facade\Db;
// 方法1:自动事务
Db::transaction(function () {
Db::table('accounts')->where('id', 1)->dec('balance', 100);
Db::table('accounts')->where('id', 2)->inc('balance', 100);
});
// 方法2:手动事务
try {
Db::startTrans();
Db::table('accounts')->where('id', 1)->dec('balance', 100);
Db::table('accounts')->where('id', 2)->inc('balance', 100);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
throw $e;
}
事务最佳实践
检查受影响行数
try {
$pdo->beginTransaction();
$stmt = $pdo->prepare("UPDATE accounts SET balance = balance - ? WHERE id = ? AND balance >= ?");
$stmt->execute([100, 1, 100]);
if ($stmt->rowCount() === 0) {
throw new Exception("账户余额不足");
}
$stmt = $pdo->prepare("UPDATE accounts SET balance = balance + ? WHERE id = ?");
$stmt->execute([100, 2]);
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
echo "错误:" . $e->getMessage();
}
嵌套事务处理
class TransactionManager {
private $pdo;
private $transactionLevel = 0;
public function beginTransaction() {
if ($this->transactionLevel === 0) {
$this->pdo->beginTransaction();
} else {
$this->pdo->exec("SAVEPOINT trans{$this->transactionLevel}");
}
$this->transactionLevel++;
}
public function commit() {
$this->transactionLevel--;
if ($this->transactionLevel === 0) {
$this->pdo->commit();
}
}
public function rollback() {
$this->transactionLevel--;
if ($this->transactionLevel === 0) {
$this->pdo->rollBack();
} else {
$this->pdo->exec("ROLLBACK TO SAVEPOINT trans{$this->transactionLevel}");
}
}
}
注意事项
- 事务隔离级别:根据业务需求设置合适的隔离级别
- 表引擎:确保使用支持事务的存储引擎(如 InnoDB)
- 异常处理:始终使用 try-catch 块处理事务
- 资源释放:及时关闭数据库连接
- 性能考虑:事务不宜过大,避免长时间锁定资源
选择哪种方式取决于你的项目框架和具体需求,PDO 和 MySQLi 适用于没有框架的项目,而 Laravel、ThinkPHP 等框架提供了更便捷的事务处理方法。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播