数据库事务系列4 事务控制语句 隔离级别
Posted 小耶哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库事务系列4 事务控制语句 隔离级别相关的知识,希望对你有一定的参考价值。
苏州天平山初冬美景 宋老师摄于2019年冬
1.事务控制语句
在mysql命令行的默认设置下,事务都是自动提交的,即执行一条sql语句后会马上执行commit操作。因此要显示的开启一个事务需要使用命令begin、start transaction,或者执行命令set autocommit=0,禁用当前会话的自动提交。
事务控制语句:
1. start transaction | begin:在存储过程中,mysql的分析器会自动将begin识别为begin……end,因此在存储过程中只能使用start transaction语句来开启一个事务。
2. commit。
3. rollback:回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。
4. savepoint identifier。
5. release savepoint identifier:删除一个事务的保存点,当没有一个保存点执行这句语句时,会抛出一个异常。
6. rollback to savepoint:这个语句与savepoint命令一起使用。可以把事务回滚到标记点,而不回滚在此标记点之前的任何操作。例如,可以发出两条update语句,后面跟一个savepoint点,后面又是两条delete语句。如果执行delete语句期间发生了异常,并且捕捉到了这个异常,同时发出了rollback to savepoint命令,事务就会回滚到指定的保存点,撤销所有的delete操作,而update操作不受影响。但是,rollback to savepoint命令并不会真正的结束事务,需要运行rollback命令之后,才会完成地回滚事务。
7. set transaction:设置事务的隔离级别。
Commit和commit work语句基本是一致的,都是用来提交事务。不同之处在于commit work用来控制事务结束后的行为是chain还是release的。如果是chain方式,那么事务就变成了链事务。
2.隐式提交的sql语句
提交数据有三中类型:显示提交、隐式提交、及自动提交。
1.显示提交:用commit命令直接完成的提交为显示提交。
2.自动提交:若把autocommit设置为ON, 则在插入、修改、删除语句执行后,系统将自动进行提交。
3.隐式提交:无需显示执行commit语句,session中的操作被自动提交到数据库的过程。
隐式提交的方式:
1. 正常执行完DDL语句,包括create\alter\drop\rename\truncate.
2. 正常执行完DCL语句,包括grant, revoke.
3. 正常退出数据库管理软件,没有明确发出commit或者rollback.
隐式提交的本质:一条DDL语句执行了两次commit
Commit;
DDL statement;
Commit;
第一个commit将当前session中未提交的事务隐式提交,以保证DDL语句失败时的回滚位置。
第二个commit将DDL操作提交。
3.对于事务操作的统计
由于InnoDB存储引擎是支持事务的,因此InnoDB存储引擎的应用需要在考虑每秒请求数(Question per second , QPS)的同时,应该关注每秒事务处理的能力(transaction per second).
计算TPS的方法是(com_commit+com_rollback)/time。但是利用这种方法计算的前提是:所有的事务必须都是显示提交的,如果存在隐式的提交和回滚,不会计算到com_commit和com_rollback变量中。
4.事务的隔离级别
大部分的数据库系统并没有实现真正的隔离性,最初或许是因为系统实现者并没有真正理解这些问题。如今这些问题已经弄清楚了,但是系统实现者在正确性和性能之间做了妥协。
SQL标准定义的四个隔离级别为:
read uncommitted(浏览访问);
read committed(游标稳定);
repeatable read(这个是没有幻读的保护);
serializable(隔离);
InnoDB存储引擎默认支持的隔离级别是repeatable read, 但是与标准的sql不同的是,InnoDB存储引擎在repeatable read隔离级别下, 使用next-key lock锁的算法,因此避免了幻读。
事务的隔离级别越低,事务请求的锁越少或者保持锁的时间就越短。
大部分用户质疑serializable隔离级别带来的性能问题,但是根据Jim Gray在《Transaction Processing》一书中指出,serializable与repeatable read开销是一样的,甚至serializable可能更优。因此选择repeatable read不会带来性能的损失,选择read committed也不会有性能的大幅提升。
设置事务的隔离级别:set[session | global] transaction isolation level {事务隔离级别};
如果想在mysql启动时就设置事务的默认隔离级别,就修改配置文件。在mysqld中添加如下行:
[mysqld]
Transaction-isolation = read-committed;
查看当前会话的事务隔离级别:select @@tx_isoltaion;
查看全局的事务隔离级别:select @@global.tx_isolation;
在serializable隔离级别下,Innodb存储引擎会对每个select语句后自动加上 lock in share mode, 因此这个隔离级别下,读占用了锁,不再支持一致性的非锁定读.其主要用在InnoDB存储引擎的分布式事务中。
往期回顾
InnoDB存储引擎系列
75道BAJT高级Java面试题专题
运维专家专题
经典回顾
微信支付专题
参考资料
1 | CSDN
责编 | 小耶哥
本期作者 | 才高7缸
平台建设及技术支持 | 小耶哥
以上是关于数据库事务系列4 事务控制语句 隔离级别的主要内容,如果未能解决你的问题,请参考以下文章