PHP 与MySQL 平台下的事务实现探讨
2012-09-12朱海岩赵新平
朱海岩,赵新平
(吕梁学院汾阳师范分校信息技术系,山西 汾阳 032200)
事务是一个或一系列查询,这些查询可以保证在数据库中作为一个整体全部执行或者全部不执行[1].一个事务所涉及的操作如果全部被执行则称为该事务被提交了,否则,数据库的状态会回到事务执行之前的状态,称为事务被回滚了.这样,数据库就可以在事务执行成功或者不成功的情况下都保持一致状态.
1 关于MyISAM和InnoDB
MySQL数据库支持许多不同的存储引擎,这些存储引擎决定了表的内部实现.数据库中的每个表可以采用不同的存储引擎,而且可以相互转换.在所有的存储引擎中,使用最广泛的是My-ISAM 和 InnoDB[2-3].大多数的数据库应用程序都会使用MyISAM或者InnoDB或者两者的结合.
MyISAM是MySQL中创建数据表所默认采用的存储引擎类型.它基于传统的ISAM(有索引的顺序访问方法)存储引擎,是用于存储记录和文件的标准方法.MyISAM具有检查和修复表格的大多数工具,该类型的表格可以被压缩,也支持全文搜索,但它们不是事务安全的,也不支持外键[4].
InnoDB是一种事务安全的存储引擎.也就是说,这种存储引擎提供了事务的提交和回滚功能,另外InnoDB还支持外键[1].虽然基于此存储引擎的数据表查询速度比MyISAM慢,但是在要求事
务安全的应用中,使用InnoDB显然会比较方便.
2 情境假设
假设某网上书店的后台数据库中存在orders和order_items两个表,其中orders表存储订单号、客户编号、订单金额和订单提交日期,order_items表存储订单编号、图书ISBN号、图书数量,两个表的逻辑结构分别为:
很显然,当一个订单被提交或者某个订单信息需要删除时,需要同时更新这两个表的数据.如果一个表得到更新而另外一个表更新失败,则数据库中就会存在不一致的状态[3].所以,对于这两个表的操作构成一个事务,要么全部完成,要么全部不做,不允许部分完成.
下面分别针对InnoDB和MyISAM存储引擎说明事务的实现方式.
3 基于InnoDB存储引擎的事务实现
3.1 用 begin(或 start transaction)、commit、rollback实现
在MySQL中,可以通过向数据库服务器发送“begin”指令或“start transaction”指令表示一个事务的开始[5].事务一旦开始,向数据库做出的所有修改操作都会被缓存,直至执行到“commit”指令.也就是说,在“commit”指令之前的对于数据库的操作并没有真正写入数据库,因此对于其它用户是不可见的.如果事务中的某个操作失败,则应该使用“rollback”指令撤销之前的其它操作,数据库会回到事务执行之前的状态[6-7].
上面提到的网上书店实例中,当一个订单被提交之后,应该向orders表、order_items表分别添加相应的信息.对这两个表的插入操作应该作为一个事务,具体操作如下:
3.2 用set改变MySQL的自动提交模式
在默认情况下,MySQL是以自动提交(autocommit)模式运行的,即向数据库发送的每一条指令都是一个事务,即时提交[8].如果某事务由多个操作组成,则此种提交方式不符合事务的要求.解决方法是可以用“set autocommit=0”指令关闭自动提交,则提交给数据库服务器的指令只是被缓存,并不立即写入数据库[9],等指令全部结束之后,用“commit”指令手动提交,事务结束后,再执
4 基于MyISAM存储引擎的事务实现
基于MyISAM存储引擎的数据表不支持事务,只能采用手动锁定数据表的方式避免并发操作可能造成的数据不一致的问题[10].基本思想是:向数据库发送“LOCK TABLES‘xyz’READ/WRITE”查询,锁定xyz表,READ表示锁定类型为读锁定,WRITE表示锁定类型为写锁定.如果一个线程获得在一个表上的READ锁,那么该线程和所有其他线程只能从表中读数据,不能进行任何写操作;如果一个线程在一个表上得到一个WRITE锁,那么只有拥有这个锁的线程可以从表中读取和写表,其它的线程被阻塞[11].当前线程向数据库服务器发送“UNLOCK TABLES”查询或当前线程与数据库服务器的连接被关闭后,所有由当前线程锁定的表被解锁.
具体操作过程如下:
5 结语
事务处理是数据库操作中一个不可回避的问题.在设计数据表时需要考虑是否会涉及事务应用,再根据具体情况选用不同的存储引擎.如果表格只是应用于大规模的查询操作,建议采用MyISAM存储引擎;如果表格应用于频繁的插入和删除操作,建议采用InnoDB存储引擎.虽然理论上可以先转换数据表的存储引擎,再去完成相应操作,但对于访问量大的数据库而言,频繁转换存储引擎是不现实的.所以基于MyISAM和InnoDB存储引擎的事务实现是从事PHP和MySQL平台Web应用开发所必须掌握的基本技能.
[1]LukeWelling,Laura Thomson.PHP和 MySQLWeb开发[M].武欣,译.北京:机械工业出版社,2009:307 -310.
[2]Paul D B,杨晓云,王建桥,等.MySQL技术内幕:第4版[M].北京:人民邮电出版社,2011:624-689.
[3]Charles A B.深入理解 MySQL:第1版[M].杨涛,王建桥,杨晓云,等译.北京:人民邮电出版社,2010:382-416.
[4]Russell J,Dyer T.MySQL 核心技术手册:第2 版[M].李红军,李冬梅,译:北京:机械工业出版社,2009:359-429.
[5]王威.MySQL数据库源代码分析及存储引擎的设计[D].南京:南京邮电大学,2012:35 -40.
[6]陈虎,唐海浩,廖江苗,等.面向批量插入优化的并行存储引擎 MTPower[J].计算机学报,2010(8):1492 -1499.
[7]李亚伟.MySQL的存储安全的研究与实现[D].武汉:华中科技大学,2011:18-23.
[8]顾治华,忽朝俭.MySQL存储引擎与数据库性能[J].计算机时代,2006(10):8-10.
[9]马永成,肖诗斌,王弘蔚,等.MySql存储引擎的研究和实现[J].计算机科学,2007,34(12):173 -175.
[10]罗凡,裴士辉,张雪松,等.MySQL中 InnoDB引擎的动态存储管理[J].东北师大学报:自然科学版,2006,38(1):22 -26.
[11]黄雅萍,刘晓强,吴成义.基于MySQL和PHP的分布式事务处理[J].东华大学学报:自然科学版,2011,37(1):81 -85.