beginTransaction()

1. 定义

该方法声明数据库启动一个事务(Transactions),未启动事务时 SQL 语句都是自动提交,而启动事务后,除了一些类似于DROP TABLE或者CREATE TABLE的 DLL 语句会隐式地自动提交(无法回滚更改)外,其余语句在显式commit()提交一个事务之前都可回滚(Rollback)。 成功启动事务时返回 true,失败则返回 false。

注:

  • DLL 语句:数据定义类语句,包括数据库、表、字段、索引等数据库对象的定义,操作包括创建(create)、修改(alter)和删除(drop)
  • DML 语句:数据操作类语句,限于数据库记录的增(insert)、删(delete)、查(select)、改(update)
  • DCL 语句:数据控制类语句,定义数据库对象的访问权限和安全级别,例如授权(grant)和取消权限(revoke)等
  • MySQL 只有 InnoDB 引擎支持事务,MYISAM 引擎并不支持事务
  • 事务提交并不会自动判断提交的所有 SQL 语句的正确性,也不会自动回滚
  • 一旦开始事务,则只能使用PDO::commit()方法或PDO::rollBack()方法来完成事务

关于数据库的具体内容可转至我们的MySQL教程

2. 语法

PDO::beginTransaction ( void ) : bool

3. 参数说明

该方法不传入任何参数。

4. 示例

<?php

// PDO::beginTransaction()
// 声明数据库启动一个事务(Transactions)

try {
    $config = ['driver' => 'mysql', 'host' => 'localhost', 'dbname' => 'test', 'charset' => 'utf8', 'user' => 'root', 'pwd' => 'mysql'];
    $dsn = sprintf('%s:host=%s;dbname=%s;charset=%s', $config['driver'], $config['host'], $config['dbname'], $config['charset']);
    $conn = new PDO($dsn, $config['user'], $config['pwd']);

} catch (PDOException $e) {
    error_log($e->getMessage()); // 将错误信息记录至日志
    echo $e->getMessage();
}

try {
    $conn->beginTransaction();// 启动一个事务
    $conn->query('DELETE FROM `movie` WHERE `id` > 0 LIMIT 1');
    $sql = "INSERT INTO `movie`(`name`, `rate`, `url`, `cover`) VALUES (:name, :rate, :url, :cover)";
    $statement = $conn->prepare($sql);
    $statement->execute(
        [
            ':name'=>'极速教程',
            ':rate'=>'9.9',
            ':url'=>'https://www.jisudev.com/',
            ':cover'=>'http://www.jisudev.com/static/images/logo.png'
        ]
    );

    $conn->query('SELECT * FROM `movie`');

    sleep(100);// 先休眠 100秒。查看数据库表变化(实际上在执行 commit() 方法前,数据库都是不变的)

    $res = $conn->commit();// 提交事务,此时事务之间的操作开始执行
    if($res) echo '事务操作成功!';
} catch (Exception $e) {
    // 发生错误时,可回滚:例如网络中断
    $conn->rollBack();
    echo "发生了错误:",$e->getMessage();
}

5. 延展阅读

  • PDO::commit():提交一个事务。同时数据库驱动返回到“自动提交”状态,直至开启下一次事务
  • PDO::rollBack():回滚一个事务(即撤销事务所做的一切改变,隐式自动提交的 DLL 类语句无法回滚)