首页 > 代码库 > MySQL的事务

MySQL的事务

MySQL的事务

1.事务:事务是由一步或者几步数据库操作序列组成的逻辑执行单元,这一系列操作要么全部执行,要么全部放弃执行。

2.事务具备的四个特性(简称为ACID性):

(1)原子性(Atomicity):

  事务是应用中最小的执行单位,具有不可再分的特征,事务是应用中最小的逻辑执行体;

(2)一致性(Consistency):

  事务执行的结果必须使数据库从一个一致性状态转变到另一个一致性的状态。当数据库只包含事务成功提交的结果时,数据库处于一致性状态。如果系统运行发生中断,某个事务尚未完成而被迫中断,而该未完成的事务对数据库所做的修改已被写入数据库,此时的数据处于一种不正确的状态,这种不正确的状态就是处于不一致性状态。一致性是通过原子性来保证的。

(3)隔离性(Isolation):

  各个事务的执行互不干扰,任意一个事务的内部操作对于其他并发的事务都是隔离的。并发执行的事务之间影响不到对方的中间状态。

(4)持续性(Durability):

  也成为持久性,指事务一但提交,对数据所做的任何改变都将记录的永久的存储器中,即物理数据库中。

3.事务组成:

(1)一组DML语句:操作数据库表中记录的语言;

(2)一条DDL语句:操作数据库对象的语言;

  注释:数据库对象指的是表(table)、数据字典、约束(constraint)、视图(view)、索引(index)、函数(function)、存储过程(procedure)、触发器(trigger)等;其中数据字典其实就是一张特殊的表,存储的是数据库相关信息,通常不被操作。

(3)一条DCL语句:数据控制语句。

其中DDL语句和DCL语句只能有一条,DDL语句可DCL语句会导致事务立即提交。

4.提交事务的方式:

(1)显式提交:使用commit关键字;

(2)自动提交:执行DDL或者DCL语句。

5.事务回滚:

  当事务所包含的任意一个数据库操作执行失败后,应该回滚(rollback)事务,使该事务中所做的修改全部失效。事务回滚的方式有两种:

(1)显式回滚:使用rollback关键字;

(2)隐式回滚:系统错误或者强行退出。

6.MySQL中的事务支持:

(1)MySQL默认关闭事务(即打开自动提交事务),在默认情况下,在MySQL控制台输入一条DML语句,该语句会立刻保存到数据库中。可以使用下面的语句来开启事务(即关闭自动提交事务):

  set autocommit = 0;(注:set autoacommit = 1——默认关闭事务)

  调用此命令后,上一个事务结束后的所有DML语句都属于同一个事务中,除非使用commit提交事务,或者运行DDL语句或DCL语句隐式的提交事务,所有的DML语句都在同一个事务中。同样也可以使用rollback回滚来结束事务,但使用rollback将会使此事务中的DML语句全部失效。

注:使用set autocommit = 0 会使得整个Session(可以简单理解为一个命令行窗口)打开事务。

  如果不想使得整个Session都打开事务可以使用start transaction或begin这两个命令临时性的开启事务,当DML语句组结束后再使用commit显式的提交事务,或者使用DDL语句或DCL语句隐式的提交事务。

(2)普通的回滚和提交都会导致事务的结束,如果使用savepoint设置事务的中间点,则rollback到中间点时,此事务不会结束。

7.有关事务提交和回滚的例子:

(1)示例1:

#创建一张表
create table students(
    s_id int not null,
    s_name varchar(255) not null
);
#插入一条记录
insert into students values(1,ywl);
#插入另一条记录
insert into students values(2,lj);
#由于在MySQL中事务是默认关闭的,所以,以上两条DML语句逐一执行时
#就会被自动提交
#执行查询:结果是students表中有两条记录
select * from students;

#在此处临时开启MySQL的事务
begin;
#修改表中的数据
update student set s_name=qq where s_id=1;
#注意,并未提交事务、
#查询一次:表被修改,但注意,这里事务并未提交,查询到的结果是个假象
#哈哈
select * from students;
#进行回滚事务
rollback;
#事务结束,由于rollback,修改表记录的DML语句未执行
#查询该表,发现该表依然处于初始状态
select * from students;

#使用start transaction与begin相同,使用同样的例子试试就好

#开启所连接Session的事务
set autocommit = 0;
update student set s_name=qq where s_id=1;
update student set s_name=bb where s_id=2;
#执行到这里其实并未提交事务,只有使用commit提交事务后
#数据表才发生变化
#提交事务
commit;

 

(2)示例2,为rollback设置中间点:

#打开事务
set autocommit = 0;
#创建表
create table teacher(
    t_id int not null,
    t_name varchar(255) not null
);
#注意,虽然这里没哟显式的使用commit提交事务,但是
#建表语句是一个DDL语句,所以其实此事务已被隐式提交

#以下为一个新的事务
insert into teacher values(1,a);
insert into teacher values(2,b);
#查询一下
#在teacher表中有内容
select * from teacher;
#直接回滚事务
rollback;
#查询teacher表,表中没有记录
select * from teacher;
#此时的事务已经结束,最终结果,没有对teacher表进行操作

#新的事务开始
insert into teacher values(1,a);
#设置rollback的中间点
savepoint a;
insert into teacher values(2,b);
#查询下teacher表
select * from teacher;
#回滚到中间点
rollback to a;
#再次查询下teacher表
select * from teacher;
#由于回滚到中间点的rollback未关闭此事务,所以可以提交事务
commit;

#查询teacher表 观察结果
select * from teacher;

 

 

 

 

 

  

MySQL的事务