事务
数据库面经:
基本sql语句:各种查询;查到的结果去重;再排序;
什么是事务
所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。事务就是一组原子性的SQL查询,或者说一个独立的工作单元。多条SQL语句看作一个整体,要么都做,要么都不做。
示例:银行转账
A账户需要将钱转给B账户。因此就需要从A账户里面扣款1000元,再给B账户里面增加1000元。整个过程并不是一次就可以完成的,而是分了好多步骤,此时如果刚好从A账户里面扣款1000元,还没有增加到B账户里面,此时程序恰好出问题了。此时A少了1000,而B并没有增加1000,所以就会出现问题。事务表达的意思就是,当A减少1000,B增加1000,此过程是一个整体,要做都做,要不做就都不做。如果做一半就进行回滚,例如A减少1000,而B不能增加1000时A就需要回滚,将1000重新给A加上,回到做之前的状态。
事务的执行条件
事务是否支持还却决于数据库的引擎。
引擎与数据库的关系
举例:
引擎相当于主机
数据库相当于显示屏
当用户把数据库安装好之后相当于有一个显示器,而显示器想要使用就必须连上主机。而主机是可以替换的,主机的系统也可以是windows或者mac或Linux,这就对应于不同的引擎。对于用户交互来说可能就只看显示器显示的内容,而显示器接那一台主机是另外的事。因此显示器还是那个显示器,而显示器呈现的内容就取决于连接哪一台主机从而呈现哪一台主机的内容。
为什么需要事务
例如转账,如果处于中间状态是不对的。因此就需要事务,需要将一些SQL语句作为一个整体来执行,要么都执行,要么都不执行。
事务的属性
ACID
原子性(atomicity)
一组SQL语句是一个整体,是一个原子操作
一致性(consistency)
从一个状态转移到另一种状态,不能存在一种之间结果。如果系统在中间崩溃是需要回滚的
隔离性(isolation)
当一个事务正在被操作的时候,在该事务完成之前,对于其他事务是不能看到该事务的
持久性(durability)
事务一旦完成就会永久保存在数据库中
InnoDB引擎四种隔离级别
- 未提交读:隔离级别最低
开启一个事务,在该事务中做的事情虽然该事务还未提交,但是在其他事务中就已经可以看见 - 提交读:隔离级别高
事务一旦提交,其他事务就可以看见结果 - 可重复读:隔离级别更高
即使别的事务提交了,当前事务依旧看不到。在一个事务中,如果该事务还没有提交。其他事务虽然完成了提交操作,这时数据库数据已经更新,但是由于当前事务还未完成,所以看不到更新的数据 - 可串行化:隔离级别最高
事务加锁,让每一个事务的执行有先后顺序。
查看当前会话隔离级别
SELECT @@SESSION.transaction_isolation;
若当前会话隔离级别修改那么仅仅只是改变当前会话,是不会影响其他人的。不会对整个系统造成改变
查看系统隔离级别
SELECT @@GLOBAL.transaction_isolation;
如果改变了系统的隔离级别那么所有人的隔离级别都会发生变化
如何将多条SQL语句视为一个整体呢?
事务是将多条SQL语句视为一个整体,那么是如何将多条SQL语句视为一个整体呢?
单条SQL语句组成的事务
单条SQL语句也是一个事务
- 先开启事务
- 执行单条SQL语句
- 完成后,自动提交
多条SQL语句组成的事务
- 手动开启事务
- 执行SQL语句1
- 执行SQL语句2
- …
- 执行SQL语句n
- 所有SQL语句执行完毕,手动提交事务
这时所执行的一系列SQL操作才会生效
开启事务的命令
- begin;
或 - start transaction;
提交事务的命令
- commit;
回滚事务的命令
- rollback;
幻读
出现幻读的前提是当前会话或者当前系统处于可重复读的隔离级别
幻读保证了在该事务中多次查询,数据是一致的
表中明明已经插入了新数据,但是在当前事务中是不能看见新数据的,因此就会出现幻读
设置隔离级别
设置全局隔离级别
- 未提交读:set global transaction isolation level READ UNCOMMITTED;
- 提交读:set global transaction isolation level READ COMMITTED;
- 可重复读:set global transaction isolation level REPEATABLE READ;
- 可串行化:set global transaction isolation level SERIALIZABLE;
设置会话隔离级别
- 未提交读: set session transaction isolation level READ UNCOMMITTED;
- 提交读:set session transaction isolation level READ COMMITTED;
- 可重复读:set session transaction isolation level REPEATABLE READ;
- 可串行化:set session transaction isolation level SERIALIZABLE;