您的位置:首页 > 数据库 > MySQL

mysql事物处理的知识点总结

2014-04-10 12:15 239 查看
事务处理在各种管理系统中都有着广泛的应用,比如人员管理系统,很多同步数据库操作大都需要用到事务处理。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!用事务处理。如果删除出错,你只要rollback就可以取消删除操作

MYSQL数据库从4.1就开始支持事务功能,据说5.0引入存储过程

MYSQL的事务处理主要有两种方法。

1、用begin,rollback,commit来实现

begin 开始一个事务

rollback 事务回滚

commit 事务确认

2、直接用set来改变mysql的自动提交模式

MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过

set autocommit=0 禁止自动提交

set autocommit=1 开启自动提交

来实现事务的处理。MYSQL中只有INNODB和BDB类型的数据表才能支持事务处理!其他的类型是不支持的

事例:

<?php

$handler=mysql_connect("localhost","root","");

mysql_select_db("task");

mysql_query("SET AUTOCOMMIT=0");//设置为不自动提交,因为MYSQL默认立即执行

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);

?>

BEGIN;
SELECT book_number FROM book WHERE book_id = 123 FOR UPDATE ;
// ...
UPDATE book SET book_number = book_number - 1 WHERE book_id = 123;
COMMIT;
-------------------------------------------------------------------------------
由于加入了FOR UPDATE,所以会在此条记录上加上一个行锁,如果此事务没有完全结束,那么其他的事务在使用SELECT ... FOR UPDATE请求的时候就会处于等待状态,直到上一个事务结束,它才能继续,从而避免了问题的发生,需要注意的是,如果你其他的事务使用的是不带FOR UPDATE的SELECT语句,将得不到这种保护。

基本命令:

开启事务

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都加上了 共享锁

出错处理

根据出错信息,执行相应的处理

其它实例:

<?php
02
$conn
=mysql_connect(
'localhost'
,
'root'
,
'yourpassword'
)
or
die
(mysql_error());
03
mysql_select_db(
'transaction'
,
$conn
);
04
mysql_query(
'set
names utf8'
);
05
06
//创建事务
07
mysql_query(
'START
TRANSACTION'
)
or
die
(mysql_error());
08
$sqlA
=
"update
A set account=account-1"
;
09
if
(!mysql_query(
$sqlA
)){
10
mysql_query(
'ROLLBACK'
)
or
exit
(mysql_error());
//判断当执行失败时回滚
11
exit
();
12
}
13
$sqlB
=
"update
B set account=account+1"
;
14
if
(!mysql_query(
$sqlB
)){
15
mysql_query(
'ROLLBACK'
)
or
exit
(mysql_error());
//判断当执行失败时回滚
16
exit
();
17
}
18
mysql_query(
'COMMIT'
)
or
die
(mysql_error());
//执行事务
19
mysql_close(
$conn
);
20
?>
以上代码可以作为模拟银行转账业务的事务流程。以表A、B分别表示两个已在银行开户的账户,当账户A执行转出1元给账户B的操作时,如果操作执行失败,转出将会回滚至原始状态,不继续向下执行动作。反之,如果操作执行成功,则账户B可用余额将增加1元,否则事务回滚至原始状态。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: