上周工作中再次使用到了事务。使用场景是执行一个sql组,包含多个sql语句。想了想,这些sql语句要么同时执行,要么同时不执行,才能够保证数据的完整性。所以简单的在sql语句正式执行的最前面加上begin(或 start transaction),在sql语句结尾加上commit。今天再来复习一下mysql中的事务。
什么是事务?
事务(TRANSACTION),就是mysql的一个具有完整逻辑的sql组,这个组里包含多个sql操作。这些sql必须同时执行,这个逻辑才算完成。要么,就回滚(rollback)到事务执行之前的数据。
最开始学习事务的时候,老师习惯讲到银行转账的情景。即a用户给b用户转账,需经过a用户扣款,b用户到账。如果在a用户扣款之后,环节发生了错误,需要a用户扣款取消,否则数据会出现a用户扣款,b用户未到账,金额的总数出现了错误。此时就需要在转账这个操作中加入事务,要么同时执行(a扣款,b到账)成功,否则回滚(a扣款,异常错误,b账号未到账,取消a扣款)。这也是事务中特性的完整性、一致性的概念。
重要:mysql的myisam类型引擎不支持事务。
事务的特性
原子性:一个事务(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会话后,则不会提交事务。
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set (0.04 sec)
以上命令来查看当前会话状态,value列的on表示当前为自动提交状态。
关闭自动提交可以执行set autocommit=0;
#0 为关闭,1为开启
mysql> set autocommit=0;