事务(transaction): 在数据库一般把需要保证原子性 、 隔离性 、 一致性和持久性 的一个或多个数据库操作称之为一个事务 。
事务是一个完整不可分割的整体,在数据库中一般认为要么全做,要么全不做的规则称为原子性。
多个事务之间相互独立。每个事务的对象对其他事务的操作对象相互分离,事务提交前对其他事务不可见。以对于现实世界中状态转换对应的某些数据库操作来说,不仅要保证这些操作以原子性的方式执行完成,而且要保证其它的状态转换不会影响到本次状态转换,这个规则被称之为隔离性 。
如果数据库中的数据全部符合现实世界中的约束(all defined rules),我们说这些数据就是 一致的,或者说符合 一致性 的。也就是事务操作前后,数据总量不变。
数据库某些操作的原子性和隔离性都是保证一致性的一种手段,在操作执行完成后保证符合所有既定的约束则是一种结果。
当现实世界的一个状态转换完成后,这个转换的结果将永久的保留,这个规则被设计数据库的大叔们称为持久性。也就是当事务提交或回滚后,数据库会持久化的保存数据
活动的(active)
事务对应的数据库正在执行过程中时,我们就称该事务处于活动状态
部分提交的(partially committed)
当事务的最后一个操作执行完成,但由于操作都在内存中执行,所造成的影响没有刷新到磁盘时,我们就说该事务处于部分提交状态。
失败的(failed)
当事务处在活动的或者部分提交的状态时可能遇到了某些错误而无法执行,或者人为的停止当前事务的执行,我们就说该事务处在失败的状态。
中止的(aborted)
当回滚操作执行完毕时,也就是数据库恢复到了执行事务之前的状态,我们就说该事务处在中止状态。
提交的(committed)
当处于部分提交的状态的事务将修改过数据都同步到磁盘上之后,我们就可以说该事务处在了提交的状态。

只有当事务处于提交的或者中止状态时,一个事务的生命周期才算是结束了。
开启事务
BEGIN(WORK)
begin语句代表开启事务,后面的WORK可有可无。
START TRANSACTION
start transaction也代表开启事务,但是其后面可以跟修饰符,多个修饰符用,隔开
READ ONLY:标识当前事务是一个只读事务,也就是属于该事务的数据库操作只能读取数据,而不能修改数据。但是只读事务可以对临时表进行增删改的。
READ WRITE:标识当前事务是一个读写事务,也就是属于该事务的数据库既可以读取数据,也可以修改数据。
WITH CONSISTENT SNAPSHOT:启动一致性读
提交事务
COMMIT(WORK):commit语句代表提交一个事务,后面的work可有可无。
手动中止事务
ROLLBACK(WORK):rollback语句就代表中止并回滚一个事务,后面的work可有可无,它可以将数据库恢复到事务执行之前的样子。ROLLBACK 语句是我们程序员手动的去回滚事务时才去使用的,如果事务在执行过程中遇到 了某些错误而无法继续执行的话,事务自身会自动的回滚。
MYSQL中有一个系统变量autocommit:
- mysql> SHOW VARIABLES LIKE 'autocommit';
- +---------------+-------+
- | Variable_name | Value |
- +---------------+-------+
- | autocommit | ON |
- +---------------+-------+
- 1 row in set (0.01 sec)
它默认为ON,也就是默认情况下,如果我们不显式使用start transaction或者begin来开启事务,那么每一条语句都算是一个独立的事务,这种特性称为自动提交。
关闭自动提交:
显式的的使用 START TRANSACTION 或者 BEGIN 语句开启一个事务。 这样在本次事务提交或者回滚前会暂时关闭掉自动提交的功能。
把系统变量 autocommit 的值设置为 OFF ,就像这样: SET autocommit = OFF;
因为某些特殊语句而导致事务提交的情况称为隐式提交。
会导致事务隐式提交的语句:
定义或修改数据库对象的数据定义语言(DDL)例如:create,alterdrop等语句。
隐式使用或修改mysql数据库中的表
例如使用alter user,create user、drop user,grant,rename user,revoke,set password等语句时会隐式提交前面语句所属于的事务。
事务控制或者关于锁定的语句。例如:当一个事务还没提交或者回滚时就又使用start transaction或者begin语句开启了另一个事务,会隐式的提交上一个事务,或者当前的autocommit系统变量的值为OFF,我们手动改为ON时,也会隐式提交事前面语句所属务。
加载数据的语句。例如:使用LOAP DATA语句来批量往数据库导入数据时,会隐式提交前边语句所属的事务
关于MySQL复制的一些语句。例如:使用start slave,stop slave,reset slave,change master to等语句会隐式提交事务
其他一些语句。例如:使用analyze table,cache index,check table(检查表),flush(清除或者重新加载缓存),load index into cache(将索引加载到缓存中),optimize table,repair table,reset等语句也会隐式提交前面语句所属的事务
保存点 (savepoint )的概念,就是在事务对应的数据库语句中打几个点,我们 在调用 ROLLBACK 语句时可以指定会滚到哪个点,而不是回到最初的原点。
设置保存点:
SAVEPOINT 保存点名称;
回滚到保存点
ROLLBACK (work) TO (SAVEPOINT)保存点名称;注意:不过如果 ROLLBACK 语句后边不跟随保存点名称的话,会直接回滚到事务执行之前的状态。也就是初始状态
删除保存点
RELEASE SAVEPOINT 保存点名称;