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

跟我一起学习MySQL技术内幕(第五版):(第二章学习日记10)

2016-04-24 01:08 597 查看
2.12事务处理

2.12.1利用事务保证语句安全执行

2.12.2使用事务保存点

2.12.3事务隔离

事务指的是一组SQL语句,他们是一个执行单位,且在必要时可以取消。

事务处理包括两个功能:提交 (commit)、回滚(rollback)。

如果某个事务里的所有语句都成功执行,可以把它提交到数据库永久性的记录下来。若果某个事务执行过程中发生了错误,则可以通过回滚操作取消该操作。出错之前的语句也将会被还原,数据库也会恢复到执行该事务之前的状态。

这两个功能可以确保尚未全部完成的操作不会影响到数据库,即不会让数据库处于部分更新(不一致)的状态。

事务的另一个用途是确保某个操作所涉及的行不会在你正在使用它们时被其它客户端修改。MySQL在执行每一条SQL语句时,会自动对该语句所涉及的资源进行锁定,以避免各个客户端之间相互干扰。

但是有些数据库操作需要多条语句才能完成。在这种情况下,不同的客户端之间就有可能出现相互干扰。事务把多条语句定义为一个执行单位,便可以防止在多客户端里可能会发生的并发问题。

事务系统通常都有四个特性 :

1.atomic (原子性)

2.consistent(一致性)

3.isolated(独立性)

4.durable(持久性)

原子性:构成事务的所有语句应该是一个独立的逻辑单元。你不能只执行他们当中的

一部分。

一致性:数据库在事务的执行前后都必须是一致的。例如,对于在某个表里的各行,

其id必须能在另外一个表里找到,否则,一个事务在试图插入带有无效id的行

时会出现失败,然后会执行回滚操作。

独立性:事务之间不能相互影响,这样并行开发时才会与挨个依次执行效果一样。

持久性:当事务执行成功完成之后,它的影响将被永久性的记录到数据库里。

事务处理为数据库操作提供了强有力的保证,但是也对cpu周期,内存和磁盘空间等方面开销提出了更多的需求。innoDB是事务安全的存储引擎,其它很多则不是事务安全。但是可以根据具体情况来进行选择存储引擎。

2.12.1利用事务保证语句安全执行

默认情况下,MySQL运行模式是自动提交,即每条语句所做的更改会自动提交,并永久保存。其实就是把每一条语句当做一个事务来处理如果想要显示地执行事务,就需要禁用自动提交模式,并主动告知MySQL何时提交,何时回滚。(使用innoDB存储引擎)

第一种执行事务方式:

start transaction;
...;
...;
commit;


中间的省略号是事务的具体内容,如插删之类的语句,以分号结尾。

第一句即挂起自动提交模式

最后一句用来结束事务,从而让所有修改持久化

如果事务的执行过程中发生错误,即可以使用
rollback;
来回滚使恢复到start之前的状态。

第二种执行事务方式:

set autocommit = 0;
set autocommit = 1;


设置为零即可禁用自动提交模式。自这句开始,后面的所有语句都是当前实物的一部分,语句范围一直延伸到你调用commit 或者 rollback。 这样做结束一个事务同时又将开始下一个事务。

set autocommit = 0;
insert into t set name = 'William';
insert into t set name = 'Wallace';
commit;
select * from t;


当执行完最后一句时,自动提交模式仍处于禁用状态。若果想要重新启用自动提交模式
set autocommit = 1;


通常情况下那些用来创建更改或删除的、数据库或其中的对象的数据定义语言(DDL)语句,以及与锁定有关于语句都不能成为事务的一部分。

alter table
create table
drop table
drop index
drop database
lock tables
rename table
set autocommit = 1(if not already set to 1)
truncate table
unlock tables (if tables currently are locked)


几点注意:

1.事务意外中断在事务提交之前会导致事务结束。此时服务器会自动回滚

2.每次断开服务器再重新连接,自动提交模式都会被自动启用。

2.12.2使用事务保存点(savepoint)

即实现部分回滚功能

create table t (i int ) engine = InnoDB;
start transaction;
insert into t values(1);
savepoint my_savepoint;
insert into t values(2);
rollback to savepoint my_savepoint;
insert into t values(3);
commit;
select * from t;


部分回滚有两个关键语句

savepoint my_savepoint;
........
rollback to savepoint my_savepoint;


回滚将在两语句间进行,所以上述事务最后结果是 :

‘ 2 ’被回滚掉了。

-----
i
-----
1
3
-----


2.12.3事务隔离

MyISAM之类的存储引擎使用了表级的锁定机制,以此保证不同客户端不能同时修改同一个表。但是难以提供很好的并发性能

InnodB存储引擎采用的是比较底层的锁定方式,为客户端提供了更细致的表访问控制,如:在一个用户修改一个表的某一行时,另一个用户可以同时读取修改同一个表里的另一个行。

这里还有一个问题:

一个客户端是否应该看到另一个客户端做出的修改

InnoDB实现了事务隔离级别功能,能够让客户端看到由其他事务所做的修改类型进行控制。

下面是一些事务同时运行时常见的错误:

1.脏读:在事务修改尚未提交时其他事务就能看到这些修改。从而导致实际并未修

改。

2.不可重复读:select语句在每次读取时可能会读取到不同的值,这发生在两次查询之

间的事务更改时。

3.幻影行:一个事务突然看到了以前没有见到的行,即一个由另一个事务中语句新增的

行.

下面是为了解决这些问题,innoDB提供的四种事务隔离级别。

read uncommited :允许看到某个事务尚未提交的行修改

read commited : 允许看到某个事务已经提交的行修改

repeatable read :select语句结果是可重复的,即使有其他事物在同时插入或修改

行。

serializable :如果某个事务正在读取某些行,其他事物将无法对这些行进行修

改,直到读取完成。

下面是隔离级别与三个问题的对应

隔离级别               脏读               不可重复读               幻影行
read  uncommited       是                是                       是
read  commited         否                是                       是
repeatable read        否                否                       否
serializable           否                否                       否


innoDB默认隔离级别是repeatable read ,更改方式有两种:

1.在服务器启动时,使用 –transaction - isolation选项

2.服务器启用时,使用 set transaction语句(三选一)

set global  transaction isolation level level_name;
set session transaction isolation level level_name;
set         transaction isolation level level_name;


其中最后一个要求有super权限的客户端才可以使用,它会作用于后续的所有客户端连接。set session transaction 会对服务器当前会话里所有的后续事务起作用。而set session只会对下一个事务起作用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: