一、什么是事务?
事务(TRANSACTION),就是mysql的一个具有完整逻辑的sql组,这个组里包含多个sql操作。这些sql必须同时执行,这个逻辑才算完成。要么,就回滚(rollback)到事务执行之前的数据。
最开始学习事务的时候,老师习惯讲到银行转账的情景。即a用户给b用户转账,需经过a用户扣款,b用户到账。如果在a用户扣款之后,环节发生了错误,需要a用户扣款取消,否则数据会出现a用户扣款,b用户未到账,金额的总数出现了错误。此时就需要在转账这个操作中加入事务,要么同时执行(a扣款,b到账)成功,否则回滚(a扣款,异常错误,b账号未到账,取消a扣款)。这也是事务中特性的完整性、一致性的概念。
包括如下SQL语句:
GRANT:授予访问权限
REVOKE:撤销访问权限
COMMIT:提交事务处理
ROLLBACK:事务处理回退
SAVEPOINT:设置保存点
LOCK:对数据库的特定部分进行锁定
二、事务的特性
原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
三、事务的执行过程
1、begin(或start transaction),开始事务。
2、执行insert、update、delete的sql语句。
3、如果sql语句执行失败,可手动rollback。回滚事务。否则执行commit提交事务。
begin; //开始事务
update account set money=money+500 where user_id=2;
update account set money=money-500 where user_id=3;
rollback; //回滚事务,回滚后,不执行后续语句,包括commit。
commit; //提交事务
四、事务的自动提交
mysql的autocommit代表事务是否自动提交。mysql默认为自动提交,即当begin开始一个事务后,关闭mysql会话窗口,没有执行rollback或者commit操作,sql语句会自动提交。当autocommit关闭后(autocommit=0),需要执行commit才会将事务提交,关闭mysql会话后,则不会提交事务。
五、例子
#建立表
CREATE TABLE `stu_mark` (
`sid` int NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`major` varchar(50) NOT NULL,
`mark` smallint NOT NULL,
PRIMARY KEY (`sid`))
#查看事务是否开启,结果为on事务为自动提交,即没有开启事务
show variables like 'autocommit';
#开启手动处理事务模式
set autocommit = false;
-- 事务的用法rollback
#开始事务(推荐)
start transaction;
#查看当前表的数据
select * from stu_mark;
#删除整张表的数据
delete from stu_mark;
#查询该表数据,发现显示删除后的结果
select * from stu_mark;
#回滚
rollback
#查看当前表的数据,发现又回来了
select * from stu_mark;
#删除整张表的数据
delete from stu_mark;
#提交事务
commit;
#查看当前表的数据,发现真删除了
select * from stu_mark;
# !!!注:rollback对于truncate和修改表结构的语句无法回滚
-- 事务的用法savepoint设置保存点
#插入一条记录
INSERT INTO stu_mark VALUES
(1011, '小黑', '体育', 99);
#保存还原点1
savepoint point1;
#插入一条记录
INSERT INTO stu_mark VALUES
(1022, '小白', '数学',98);
#保存还原点2
savepoint point2;
#查看当前效果
select * from stu_mark;
#回滚到某个还原点
rollback to point1;
#提交事务
commit;
#查看返回point1的效果,发现提交之后只有point1的数据
select * from stu_mark;