在企业开发中,数据库相关的知识是必不可少需要掌握的知识点,但对于大部分CRUD程序员,虽然很多知识我们在日常开发中确实用不到,可是当我们打算换工作时,面试的人就喜欢问那些八股文,很无奈却又必须要知道,他们不知道你的水平也没法通过其他方面了解你,所以最后就只能考察你的八股文背的如何,话不多说言归正传。
事务的特性,也就是我们常说的ACID,整理成表格就是下面这些:
名称 | 解释 |
---|---|
Atomicity(原子性) | 事务是不可分割的最小操作单元,要么全部成功,要么全部失败 |
Consistency(一致性) | 事务完成时,必须使所有数据都保持一致状态 |
Isolation(隔离性) | 数据库允许多个并发事务同时对数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致 |
Durability(持久性) | 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失 |
对于事务的ACID这里就不过多的解释了,学习数据库知识时都应该接触到,典型的场景就是两个帐号间进行转账,如果没有事务进行控制,当A帐号扣减金额后在B帐号添加金额前系统出现问题,就会导致系统中两个帐号余额不一致的问题,要解决这种问题,只需要保证帐号在进行扣减和增加金额两个步骤在一个事务中就能够避免数据不一致的问题。
上面这些是数据库中事务必须保证的,而多个事务同时操作数据库,为了避免多个事务之间的相互影响,就引出了事务的隔离级别,在不同的隔离级别下事务会产生不同的问题,数据库中的隔离级别分为如下几个级别:
事务隔离级别 | 解释 |
---|---|
读未提交 | 读到其他事务未提交的数据,这种隔离级别会产生脏读问题 |
读已提交 | 读到其他事务提交的数据,可能导致两次读取结果不一致,这种隔离级别会产生不可重复读问题,Oracle默认的隔离级别 |
可重复读 | 每次读取的结果都一样,这也是MySQL默认的隔离级别,但是会产生幻读问题 |
串行化 | 这是最高的隔离级别,所有操作指令都是按照顺序执行 |
接下来演示在MySQL中各种不同的隔离级别以及所带来的问题。
首先查看一下MySQL中的隔离级别:
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ |
+-------------------------+
1 row in set (0.00 sec)
上面表示MySQL默认的是可重复读的隔离级别,修改MySQL的隔离级别使用下面这个指令:
mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
这样就把当前session的隔离级别调整为读已提交了;在MySQL中对应几个隔离级别设置的关键字如下:
事务隔离级别 | 设置的关键字 |
---|---|
读未提交 | read uncommitted |
读已提交 | read committed |
可重复读 | repeatable read |
串行化 | serializable |
- 验证读未提交的问题:开启两个session,调整对应的隔离级别为读未提交,这时可以观察到一个事务读取到了另外一个事务未提交的数据了:先在一个事务中查询到的数据(如图中第1步);这时另外一个事务对数据进行了修改,但是这个事务还没有提交(如图中第2步);在另外一个事务中可以查询到其他事务未提交的数据(如图中第3步)。
- 验证读已提交:在一个事务内读取到其他事务提交的数据,这样就会导致当前事务中前后两次读取到的数据不一致:下面这张图按照标记的顺序依次执行,会发现在一个事务内部读取到了其他事务提交到数据,导致同一个事务内前后两次读取到的数据不一致
- 可重复读:在一个事务内多次读取到的数据是一致的,但是如果在一个事务内操作某一条记录刚好这条记录已经被其他事务处理了,这样就会导致当前事务内操作失败,但是期望的结果应该是成功的:下面这张图演示了可重复读导致的幻读问题,当一个事务进行插入数据之前先判断一下数据是否存在,不存在的数据执行插入数据操作,当事务判断数据不存在后由其他事务提交了这条数据,这就导致当前事务一直查询不到数据又不能插入数据。
- 串行化:所有的指令都是按照顺序执行,前一个指令为完成后面的指令就会被阻塞中:下面这个图展示的是串行化隔离级别的执行过程,两条插入命令分别在事务中执行,第一个事务插入成功后还没有提交事务时,第二个事务只能等待执行;只有第一个事务提交后第二个事务命令才会继续执行。
以上就是通过MySQL数据库展示事务在各个隔离级别下的运行过程,通过示例可以很好的理解隔离级别的运行过程,希望可以帮到大家对数据库的隔离级别理解。
插播一条链接:https://gitee.com/dream_xin2013/tegr。这是一个有关分布式IM消息的系统
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/181867.html