一、数据的四大特征ACID
1.1 原子性(Atomicity):事务是数据库的逻辑工作单位,它对数据库的修改要么全部执行,要么全部不执行。用事务实现。
1.2 一致性(Consistemcy):事务执行前后,数据库的状态都满足所有的完整性约束。
1.3 隔离性(Isolation):并发执行的事务之间是隔离的,保证多个事务互不影响。有几个隔离级别。
1.4 持久性(Durability):一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
二、数据库的隔离级别
2.1 读未提交:一个事务可以读取到另一个事务未提交的修改。这会带来脏读、幻读、不可重复读问题。(基本没用)
2.2 读已提交:一个事务只能读取另一个事务已经提交的修改。其避免了脏读,但仍然存在不可重复读和幻读问题。
2.3 可重复读:同一个事务中多次读取相同的数据返回的结果是一样的。其避免了脏读和不可重复读问题,但幻读依然存在.
2.4 串行化:事务串行执行。避免了以上所有问题。
2.5 名词解释:
脏读(dirty read):一个事务可以读取另一个尚未提交事务的修改数据. 这个未提交的数据有可能会被回滚(放弃),所以叫脏读。
非重复读(nonrepeatable read): 在同一个事务中,同一个查询在T1时间读取某一行,在T2时间重新读取这一行时候,这一行的数据已经发生修改,可能被更新了(update),也可能被删除了(delete), 前后读取的不一致可能会对程序逻辑造成影响。
幻像读(phantom read):同上, 一个是update, 一个是insert区别。
串行化: 串行执行事务。不存在并发。
参考例子:
https://www.cnblogs.com/kingcat/archive/2013/09/23/3334317.html
三、事务实现原理(mysql)
通过mvcc来实现的。MVCC的全称是“多版本并发控制”。
在InnoDB中,给每行增加两个隐藏字段一个用来记录数据行的创建时间,另一个用来记录行的过期时间(删除时间)
3.1 SELECT
读取创建版本小于或等于当前事务版本号,并且删除版本为空或大于当前事务版本号的记录。这样可以保证在读取之前记录是存在的。
3.2 INSERT
将当前事务的版本号保存至行的创建版本号
3.3 UPDATE
新插入一行,并以当前事务的版本号作为新行的创建版本号,同时将原记录行的删除版本号设置为当前事务版本号
3.4 DELETE
将当前事务的版本号保存至行的删除版本号
四、实例
超买:
https://blog.csdn.net/gaoxuaiguoyi/article/details/47304615
五、 编写复杂sql
5.1 先拆解业务几个步骤的sql
5.2 合成sql, 把几个步骤的sql作为临时表去合。 一般放在where或者from后面。
5.3 优化sql。 把from后面的一些逻辑可以移动到where后面甚至不用临时表了。