18.7  PDO的事务处理

事务是确保数据库一致的机制,是一个或一系列的查询,作为一个单元的一组有序的数据库操作。如果组中的所有SQL语句都操作成功,则认为事务成功,那么事务被提交,其修改将作用于所有其他数据库进程。即使在事务的组中只有一个环节操作失败,事务也不成功,整个事务将被回滚,该事务中的所有操作都将被取消。事务功能是企业级数据库的一个重要组成部分,因为很多业务过程都包括多个步骤。如果任何一个步骤操作失败,则所有步骤都不应发生。事务处理有4个重要特征:原子性(Atomicity)、一致性(Consistency)、独立性(Isolation)和持久性(Durability),即ACID。在一个事务中执行的任何工作,即使它是分阶段执行的,也一定可以保证该工作会安全地应用于数据库,并且在工作被提交时,不会受到其他连接的影响。

18.7.1  MySQL的事务处理

在MySQL 4.0及以上版本中均默认启用事务,但MySQL目前只有InnoDB和BDB两个数据表类型才支持事务,两个表类型具有相同的特性,InnoDB表类型具有比BDB还丰富的特性,速度更快,因此,建议使用InnoDB表类型。创建InnoDB类型的表实际上与创建任何其他类型的表的过程类似,如果数据库没有设置默认的表类型,就需要在创建时显式指定将表创建为InnoDB类型。创建InnoDB类型的雇员表employees,代码如下所示:

CREATE TABLE employees(…)  TYPE=InnoDB;     //使用TYPE指定表类型为InnoDB

在默认情况下,MySQL是以自动提交(autocommit)模式运行的,这就意味着所执行的每条语句都会立即写入数据库。如果使用事务安全的表格类型,是不希望有自动提交的行为的。要在当前的会话中关闭自动提交,执行如下所示的MySQL命令:

MySQL>   SET AUTOCOMMIT = 0;                         //在当前的会话中关闭自动提交

如果自动提交被打开了,必须使用如下语句开始一个事务;如果自动提交是关闭的,则不需要使用这条命令,因为当输入一条SQL语句时,一个事务将自动启动。

MySQL> START   TRANSACTION;                       //开始一个事务

在完成了一组事务的语句输入后,可以使用如下语句将其提交给数据库。这样,该事务才能在其他会话中被用户看见。

MySQL> COMMIT;                                        //提交一个事务给数据库

如果改变主意,可以使用如下语句将数据库回到以前的状态。

MySQL> ROOLBACK;                                     //事务将被回滚,所有操作都将被取消

并不是每种数据库都支持事务,PDO只为能够执行事务的数据库提供事务支持。所以当第一次打开连接时,PDO需要在“自动提交(auto-commit)”模式下运行。如果需要一个事务,那么必须使用PDO对象中的beginTransaction()方法来启动一个事务。如果底层驱动程序不支持事务,那么将会抛出一个PDOException异常。可以使用PDO对象中的commit()或rollback()方法来结束一个事务,这取决于事务中运行的代码是否成功。

18.7.2  构建事务处理的应用程序

例如,一次在线购物的过程,选好一款产品,价格为80元,采用网上银行转账方式付款。假设用户userA向用户userB的账户转账,需要从userA账户中减去80元,并向userB账户加上80元。首先,在demo数据库中准备一张InnoDB类型的数据表(account),用于保存两个用户的账户信息,包括其姓名和可用现金数据,并向表中插入userA和userB的数据记录,代码如下所示:

在下面的示例中,这个转账过程需要执行两条SQL命令,真实场景中还会有其他步骤。为了保证数据的一致性,需要把此过程变成一个事务,确保数据不会由于某个步骤执行失败而遭到破坏,代码如下所示:

在上面的示例中,模拟了userA向userB转账80元的过程。这个过程需要两条更新语句合作来完成,所以采用了事务处理,确保这两条SQL语句对数据操作的一致性。两条更新分别完成都很简单,但通过将这两条更新语句包括在beginTransaction()和commit()调用中,并通过try区块试着执行,就可以保证在更改完成之前,其他人无法看到更改。如果发生了错误,则catch区块可以回滚事务开始以来发生的所有更改,并打印一条错误消息。

《细说PHP》第四版 样章 第18章 数据库抽象层PDO 9的更多相关文章

  1. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 1

    现在,如果你已经能熟练地使用MySQL客户端软件来操作数据库中的数据,就可以开始学习如何使用PHP来显示和修改数据库中的数据了.PHP提供了标准的函数来操作数据库.在PHP 5以上的版本中可以使用My ...

  2. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 12

    18.9  管理表books实例 在Web项目中,几乎所有模块都要和数据表打交道,而对表的管理无非就是增.删.改.查等操作,所以熟练掌握对表进行管理的这些常见操作是十分有必的.本例为了能更好地展示PD ...

  3. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 11

    18.8.3  完美分页类的代码实现 分页类的编写除了需要使用在18.8.2节中提供的可以操作的3个成员方法,还需要更多的成员,但其他的成员方法和成员属性只需要内部使用,并不需要用户在对象外部操作,所 ...

  4. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 7

    18.6  PDO对预处理语句的支持 在生成网页时,许多PHP脚本通常都会执行除参数外其他部分完全相同的查询语句.针对这种重复执行一个查询,但每次迭代使用不同参数的情况,PDO提供了一种名为预处理语句 ...

  5. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 4

    18.4  创建PDO对象 使用PDO在与不同数据库管理系统之间交互时,PDO对象中的成员的方法是统一各种数据库的访问接口,所以在使用PDO与数据库交互之前,首先要创建一个PDO对象.在通过构造方法创 ...

  6. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 10

    18.8  设计完美分页类 数据记录列表几乎出现在Web项目的每个模块中,假设一张表中有十几万条记录,我们不可能一次全都显示出来,当然也不能仅显示几十条.为了解决这样的矛盾,通常在读取时设置以分页的形 ...

  7. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 8-1

    18.6.5  获取数据 PDO的数据获取方法与其他数据库扩展非常类似,只要成功执行SELECT查询,都会有结果集对象生成.不管使用PDO对象中的query()方法,还是使用prepare()和exe ...

  8. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 8

    18.6.4  执行准备好的查询 当准备好查询并绑定了相应的参数后,就可以通过调用PDOStatement类对象中的execute()方法,反复执行在数据库缓存区准备好的语句了.在下面的示例中,向前面 ...

  9. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 6

    18.5.3  PDO的错误处理模式 PDO共提供了3种不同的错误处理模式,不仅可以满足不同风格的编程,也可以调整扩展处理错误的方式. 1.PDO::ERRMODE_SILENT 这是默认模式,在错误 ...

随机推荐

  1. orm终极大爆炸

    orm终极 甩一个代码给你 # 创建字段 class Field: def __init__(self, name, column_type, primary_key, default): self. ...

  2. mysql5.7 找回密码

    初次接触数据库,二进制安装了mysql5.7以后发现无法像yum一样在日志中找回初始密码~so 首先关掉启动的数据库: 在my.cnf中新增一句: skip-grant-tables  保存退出重启m ...

  3. 20182320《Program Design and Data Structures》Learning Summary Week9

    20182320<Program Design and Data Structures>Learning Summary Week9 1.Summary of Textbook's Con ...

  4. [译]Vulkan教程(04)基础代码

    [译]Vulkan教程(04)基础代码 General structure 通用结构 In the previous chapter you've created a Vulkan project w ...

  5. swoole视频直播

    $serv=new swoole_websocket_server("0.0.0.0",9501);$client=array();$serv->on("open& ...

  6. Java之ssh框架spring配置文件配置定时任务

    最近做了一个数据同步功能,要求晚上0点去定时同步数据,这是个老项目框架用的ssh,定时任务基于quartz,废话不多说,下面详细说说相关配置. 在spring的配置文件中: <!-- 0点定时任 ...

  7. sql书写和执行顺序

    (8)SELECT (9)DISTINCT<select_list> (1)FROM <left_table> (3)<join_type> JOIN<rig ...

  8. Docker 零碎

    Delete none tag docker image: $ docker stop $(docker ps -a | grep "Exited" | awk '{print $ ...

  9. 总结在ssm整合中,Mybatis出现Mapped Statements collection already contains value for xxxxx的解决方案

    先贴一段报错信息: 前面的都不是很重要,看最后灰色标注的那段.... 严重: 异常将上下文初始化事件发送到类的侦听器实例.[org.springframework.web.context.Contex ...

  10. 【C#】学习笔记(4) 值类型和引用类型相关(Null相关)

    Reference and Value Types Value Types(值类型): struct(结构体) 独立的实例或者是拷贝 值的改变不会影响其它拷贝 值就是它所代表的信息 没有引用,所以不可 ...