目录
1.数据库事务概述
1.1 存储引擎支持情况
可以使用 SHOW ENGINES 命令查看MySQL支持事务的存储引擎有哪些
1.2 事务基本概念
事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态
事务处理的原则:保证所有事物都作为一个工作单元来执行,即使出现了故障,都不能改变这汇总执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交,那么这些修改就永久地被保存了下来;要么数据库将放弃所作的所有修改,整个事务回滚到最初状态。
1.3 事务的ACID特性
原子性
原子性
原子性是指事务是一个不可分割的工作单位,要么全部提交,要么全部失败回滚。
一致性
根据定义,一致性是指事务执行前后,数据从一个合法性状态变换到另一个合法性状态。这种状态是语义上的而不是语法上的,和具体的业务有关。
合法状态:满足预定约束的状态就叫做合法状态。简单来说,这个状态是由具体业务来定义的。满足这个状态,数据就是一致的,否则就是不一致的。如果事务中某个操作失败了,系统就会自动撤销当前正在执行的事务,返回到事务操作之前的状态。
举例1:A账户有200元,转给B300元,此时A账户余额-100元。我们自然就会发现数据是不一致的,因为我们人为定义了一个状态,账户余额不能 < 0。
举例2:A账户有200元,转50给B,A账户减少了200元,但B账户因为各种意外,余额并没有增加。此时我们也知道数据时不一致的,因为我们人为的定义了一个状态,A+B的总余额必须不变。
隔离性
一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性
一个事务一旦被提交,此事务对数据库中数据的改变就是永久性的,接下来其他操作和数据库故障不应该对其有任何影响。
持久性是通过事务日志来保证的。日志包括重做日志和回滚日志。当我们通过事务对数据进行修改的时候,首先会将数据的变化信息记录到重做日志中,然后再对数据库中对应的行进行修改。这样即使数据库系统崩溃,数据库重启后也能找到没有更新到数据库中的重做日志,继而重新执行,使事务具有持久性。
总结:原子性是基础,隔离形是手段,一致性是约束条件,持久性是我们的目的。
1.4 事务的状态
活动的
活动的
事务对应的数据库操作正在执行过程中时,我们就说该事务处在活动的状态
部分提交的
当事务中最后一个操作执行完成,所造成的影响还没有被刷新到磁盘时,我们就说该事务处在部分提交的状态。
失败的
当事务处在活动的或部分提交的状态时,可能遇到了某些错误(数据库自身错误,操作系统错误,外界环境因素等)而无法继续执行,或人为的停止当前事务的执行,我们就说该事务处在失败的状态。
中止的
如果事务执行了一部分而转变为失败的状态,那么就需要把已经修改的事务中的操作还原到事务执行前的状态,我们把这个过程称为回滚。当回滚结束后,我们就说该事务处在中止的状态。
提交的
当一个处在部分提交的状态的事务将修改过的数据都同步到磁盘上后,我们就说该事务处在提交的状态。
状态图如下:
2.如何使用事务
2.1 显式事务
步骤1:START TRANSACTION 或者 BEGIN,作用是显式的开启一个事务
步骤1:START TRANSACTION 或者 BEGIN,作用是显式的开启一个事务
START TRANSACTION 相较于 BEGIN特别之处在于,后main能跟随几个修饰符:
READ ONLY:只读事务,该事务内只能读取数据,不能修改数据
READ WRITE:读写事务,该事务内可读可写。
WITH CONSISTENT SNAPSHOT:启动一致性读
步骤2:一系列事务中的操作
步骤3:提交事务 或 中止(回滚)事务
提交事务:COMMIT;
中止(回滚)事务:ROLLBACK
回滚到某个保存点:ROLLBACK TO 【SAVEPOINT】
SAVEPOINT相关操作:
创建保存点:SAVEPOINT 保存点名称;
删除保存点:RELEASE SAVEPOINT 保存点名称;
2.2 隐式事务
关键字:autocommit ON代表自动提交事务
关闭自动提交:SET autocommit = FALSE;
在autocommit = TRUE的情况下,使用START TRANSACTION 或者 BEGIN,DML操作就不会自动提交数据。
2.3 隐式提交数据的情况
数据定义语言(DDL)会自动提交数据
数据定义语言(DDL)会自动提交数据
数据库对象为数据库、表、视图、存储过程等结构。当我们使用CREATE、ALTER、DROP语句去修改数据库对象时,就会隐式的提交前边语句所属于的事务。
隐式使用或修改MySQL数据库中的表
当我们使用ALTER、USER、CREATE USER、DROP USER、GRANT、RENAME USER、REVOKE、SET PASSWORD等语句时,会隐式的提交前边语句所属于的事务。
事务控制或关于锁定的语句
1.当我们在一个事务还没提交或回滚时就又使用START TRANSACTION 或者 BEGIN语句开启了另一个事务时,会隐式的提交上一个事务。
2.当前autocommit值为OFF,我们手动把他调整为ON时,也会隐式提交前边语句所属的事务。
3.使用LOCK TABLES、UNLOCK TAVLES等关于锁定的语句也会隐式的提交前边语句所属的事务。
加载数据的语句
使用LOAD DATA语句来批量往数据库中倒入数据时,也会隐式提交前边语句所属的事务。
MySQL复制的一些语句
START SLAVE、STOP SLAVE、RESET SLAVE、CHANGE MASTER TO等语句时会隐式提交前边语句所属的事务
其他一些语句
使用ANALYZE TABLE、CACHE INDEX、CHECK TABLE、FLUSH、LOAD INDEX INTO CHACHE、OPTIMIZE TABLE、PERIAIR TABLE、RESET等语句也会隐式提交前边语句所属的事务
3.事务的隔离级别
3.1 数据并发问题
脏写
脏写
对于两个事务,事务A修改了另一个未提交事务B修改过的数据。
脏读
事务A读取了被事务B更新但还没提交的数据。
不可重复读
事务A读取了一个数据,事务B更新了此数据,事务A再次读取同一个数据,发现值不同。
幻读
事务A从表中读取了一些行数据,事务B在该表中插入了一些新的行,事务A再次读取同一个表,发现多出几行。
3.2 SQL中四种隔离级别
READ UNCOMMITTED:未提交读,所有事务都可以看到其他未提交事务的执行结果。
READ COMMITTED:读已提交,一个事务只能看见已经提交事务所做的改变。
REPEATABLE READ:可重复读,事务A读取到一条数据后,此时事务B对改数据进行了修改并提交,事务A再次读取该数据,读到的还是事务B修改前的值。
SERIALIZABLE:可串行化,确保事务可以从一个表中读取相同的行。在此事务执行期间,禁止其他事务对改表执行插入、修改、删除操作。
注:任何一种隔离级别都会禁止脏写。
3.3 MySQL中四种隔离级别
MySQL支持上述四种隔离级别,但与SQL标准中所规定的各级隔离级别允许出现的问题有些出入,MySQL在REPEATABLE READ(可重复读)级别下可以禁止幻读问题的发生。