持续更新以及完善中…
数据库事务隔离
首先,为什么要有事务隔离呢?
在单线程下,没什么大碍,但是我们想要提高效率,采用多线程并发时,便会出现一些问题。
**下面的问题一定要当作一个事务来看待!!!!**不要觉得连续两次查询就是一次事务了,这里的两次查询是处于同一个事务,你可以当作两次查询一次是写在函数开头,一次是写在了函数末尾。
void task(){
selectBySql();
.....干了其他事情,或者没干。
selectBySql();
}
- 脏写
A有100块,现在给自己又转了20(就变成120了),现在B给A转了20块(变成了140),但是A转给自己20的事务因为某些原因出错导致回滚,又变成了100块。导致B不管先一步提交(120)还是后一步提交(140),都不是120块。
- 脏读
A转给自己20块,B读取了A资产发现有120块,但是A又因为某些问题导致回滚,B再去读A的资产发现变成了100块
- 不可重复读
- 幻读
A查询比自己财产更多的用户,发现只有C用户。
这个时候B和D用户开了账户,并转了很多钱进去。
A再次查询比自己财产更多的用户,发现出现了C,B,D用户(这是上次读取时未出现过的啊)
read uncommit(读未提交)
Oracle默认隔离规则。(效率高)
读数据不需要锁,写数据需要锁。
解决了脏写问题(写操作互斥)
但是出现脏读问题。
read commit(读已提交)
MySQL默认隔离规则(效率较高)。
只有更新事务成功提交,才能查询到本次更新.
A转账给自己20(初始100块),必须提交成功,其他人查询A的资产时才能看到120块.
解决脏读问题.
插播一条(MVCC)
MVCC
mutil version concurrent control
多版本并发控制,同一时刻同一条记录在系统中可以存在多个版本
只有当写数据事务提交时,才能读到最新的数据。
通过Read View (一致性视图)。
害,东西太多太多了,本人现在的理解就是。
初始阶段,A的资产记录是version1.0。 A执行更新的事务(更新到version2.0),然后B去读A的资产,只要是A执行更新事务没有提交,只能读到version1.0的数据。当A回滚时不会出现问题,当A提交后数据库中A资产数据更新到version2.0,但B需要提交本次查询事务,在下一次查询的时候才能看到version2.0的数据…
REPEATABLE READ(可重复读)
在整个事务过程中该事务看到的记录,自始至终都是一样的。
A转账给自己20(初始100块),必须提交成功
其他人查询A的资产时的事务也提交后,随后的查询事务才能读取到120块.
serializable (串行)
解决所有问题。但是效率最低,无并发,读和写都需要上锁。
画饼
看到舍友们在复习数据库期末考试, 然后想到上学期学的时候对于事务以及并发这里学校并未怎么讲到.
然后学后端现在也开始进入到处理分布式,并发这些问题了.
先给自己挖一个数据库学习的坑吧.