事务处理是大型应用像银行,支付宝宝这类应用可能会用到的,就是当我们数据处理不成功能时要把数据清除回滚,下面我来介绍mysql事务处理的实例,各位朋友可参考.
MYSQL的事务处理主要有两种方法.
1、用begin,rollback,commit来实现
begin 开始一个事务,rollback 事务回滚,commit 事务确认
2、直接用set来改变mysql的自动提交模式
MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行,我们可以通过.
set autocommit=0 禁止自动提交
set autocommit=1 开启自动提交
来实现事务的处理,当你用 set autocommit=0 的时候,你以后所有的SQL都将做为事务处理,直到你用commit确认或rollback结束.
注意当你结束这个事务的同时也开启了个新的事务,按第一种方法只将当前的作为一个事务.
只有InnoDB支持事务,事务 ACID Atomicity(原子性)、Consistency(稳定性)、Isolation(隔离性)、Durability(可靠性)
1、事务的原子性:一组事务,要么成功,要么撤回.
2、稳定性:有非法数据,外键约束之类,事务撤回.
3、隔离性:事务独立运行,一个事务处理后的结果,影响了其他事务,那么其他事务会撤回.事务的100%隔离,需要牺牲速度.
4、可靠性:软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改,可靠性和高速度不可兼得,innodb_flush_log_at_trx_commit选项 决定什么时候吧事务保存到日志里.
开启事务:START TRANSACTION 或 BEGIN
提交事务,关闭事务:COMMIT
放弃事务,关闭事务:ROLLBACK
折返点:SAVEPOINT adqoo_1,ROLLBACK TO SAVEPOINT adqoo_1
发生在折返点 adqoo_1 之前的事务被提交,之后的被忽略.
事务的终止,设置"自动提交"模式
SET AUTOCOMMIT = 0
每条SQL都是同一个事务的不同命令,之间由 COMMIT 或 ROLLBACK隔开
掉线后,没有 COMMIT 的事务都被放弃.
事务锁定模式
系统默认:不需要等待某事务结束,可直接查询到结果,但不能再进行修改、删除.
缺点:查询到的结果,可能是已经过期的.
优点:不需要等待某事务结束,可直接查询到结果.
需要用以下模式来设定锁定模式:
1、SELECT …… LOCK IN SHARE MODE(共享锁)
查询到的数据,就是数据库在这一时刻的数据,其他已commit事务的结果,已经反应到这里了.
SELECT 必须等待,某个事务结束后才能执行.
2、SELECT …… FOR UPDATE(排它锁)
例如 SELECT * FROM tablename WHERE id<200,那么id<200的数据,被查询到的数据,都将不能再进行修改、删除、SELECT …… LOCK IN SHARE MODE操作一直到此事务结束
共享锁 和 排它锁的区别:在于是否阻断其他客户发出的 SELECT …… LOCK IN SHARE MODE命令.
3、INSERT / UPDATE / DELETE
所有关联数据都会被锁定,加上排它锁.
4、防插入锁
例如 SELECT * FROM tablename WHERE id>200,那么id>200的记录无法被插入
5、死锁
自动识别死锁,先进来的进程被执行,后来的进程收到出错消息,并按ROLLBACK方式回滚
innodb_lock_wait_timeout = n 来设置最长等待时间,默认是50秒
事务隔离模式:
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL
READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE
1、不带SESSION、GLOBAL的SET命令
只对下一个事务有效
2、SET SESSION
为当前会话设置隔离模式
3、SET GLOBAL
为以后新建的所有MYSQL连接设置隔离模式(当前连接不包括在内)
隔离模式:READ UNCOMMITTED
不隔离SELECT,其他事务未完成的修改(未COMMIT),其结果也考虑在内
READ COMMITTED
把其他事务的 COMMIT 修改考虑在内,同一个事务中,同一 SELECT 可能返回不同结果.
REPEATABLE READ(默认)
不把其他事务的修改考虑在内,无论其他事务是否用COMMIT命令提交过,同一个事务中,同一 SELECT 返回同一结果,前提是本事务,不修改.
SERIALIZABLE,和REPEATABLE READ类似,给所有的SELECT都加上了 共享锁,一般MYSQL数据库默认的引擎是MyISAM,这种引擎不支持事务,如果要让MYSQL支持事务,可以自己手动修改.
方法如下:1.修改c:/appserv/mysql/my.ini文件,找到skip-InnoDB,在前面加上#,后保存文件.
2.在运行中输入:services.msc,重启mysql服务。
3.到phpmyadmin中,mysql->show engines;(或执行mysql->show variables like 'have_%'; ),查看InnoDB为YES,即表示数据库支持InnoDB了,也就说明支持事务transaction了.
4.在创建表时,就可以为Storage Engine选择InnoDB引擎了,如果是以前创建的表,可以使用mysql->alter table table_name type=InnoDB;
或 mysql->alter table table_name engine=InnoDB;来改变数据表的引擎以支持事务.
原理,代码如下:
- function Tran( $sql ) {
- $judge = 1;
- mysql_query('begin');
- foreach ($sql as $v) {
- if ( !mysql_query($v) ) {
- $judge = 0;
- }
- }
- if ($judge == 0) {
- mysql_query('rollback');
- return false;
- }
- elseif ($judge == 1) {
- mysql_query('commit');
- return true;
- }
- }
例,代码如下:
- <?php
- $handler=mysql_connect("localhost","root","");
- mysql_select_db("task");
- mysql_query("SET AUTOCOMMIT=0");
- mysql_query("BEGIN");
- if(!mysql_query("insert into trans (id) values('2')"))
- {
- mysql_query("ROOLBACK");
- }
- if(!mysql_query("insert into trans (id) values('4')"))
- {
- mysql_query("ROOLBACK");
- }
- mysql_query("COMMIT");
- mysql_close($handler);
- ?>
|