这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记
请思考如下场景:
小B做了一个短视频APP,获得了很好的反响。他的老板觉得短视频APP没有商城功能简直是对短视频APP的侮辱,于是就让小D去给这个短视频APP加一个商城功能。
小D一寻思,这功能简单啊,不就是对数据库进行操作吗?于是啪啪啪地写完了相关功能,轻轻松松就上线了。
小T是这个短视频APP的忠实用户,这天他看到了这APP新增了个商城功能,非常高兴,毕竟短视频APP的精髓就是电子商城。他左看右看,终于看到了自己心仪的商品,于是小手一点,就把这个商品给买下了。
卖家也是十分高兴,毕竟开店第一天,就有许多顾客购买他的商品。可是他没高兴多久,就发现了问题:100元一件的商品,卖了100件,为啥只获得了9800元?
为什么会出现这种情况呢?
原来,是小D没有使用事物。
什么是事物?
在MySQL数据库中,事物是一系列的数据库操作序列,这些操作要么全做要么全不做,是不可分割的。
事物的四大特性
事物的四大特性又称ACID原则,它们分别是
原子性(Atomicity)
一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性(Consistency)
在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。比如,在银行转账时,转账者和被转账者的金额总数相等。又比如,在前面的例子里,卖出了100件商品就应该受到100件商品的钱。
隔离性(Isolation)
数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。
持久性(Durability)
事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
当然,事物也存在一些问题,具体请往下看:
MySQL事物的一些问题
脏读
脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
例如:
某商品的价格为100元,事物A将它改为80元,但事物A还未提交。
在这个时候,事物B正在读取该商品的价格,读到了80元。
然后,事物A发生了一些异常,回滚了数据,该商品的价格又变回了100元。
在这个时候,事物B读取的价格就是80元,是脏数据,这个过程也被称为脏读。
幻读
是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
例如:
事物A查找所有价格在100元以上的商品,并将它们的价格调成为原来的80%
这时候,事物B插入了一个110元的商品。
于是,事物A就会发现还有一个商品它没有修改。
不可重复读
是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
不可重复读就不举例了。
那么,MySQL是如何解决这些问题的呢?
事物的隔离级别
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| Read Uncommitted(读未提交) | 有 | 有 | 有 |
| Read Committed(读已提交) | 无 | 有 | 有 |
| Repeatable(可重复读) | 无 | 无 | 有 |
| Serializable(串行化) | 无 | 无 | 无 |
可以看到,事物的隔离级别中,从上至下越来越严格,效率自然也越来越低。
一般在事务中选择Read Committed(读已提交)即可。