持续更新以及完善中…………………

数据库事务隔离

首先,为什么要有事务隔离呢?

在单线程下,没什么大碍,但是我们想要提高效率,采用多线程并发时,便会出现一些问题。

下面的问题一定要当作一个事务来看待!!!!不要觉得连续两次查询就是一次事务了,这里的两次查询是处于同一个事务,你可以当作两次查询一次是写在函数开头,一次是写在了函数末尾。

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块

  • 不可重复读

image-20240609160520923

  • 幻读

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 (串行)

解决所有问题。但是效率最低,无并发,读和写都需要上锁。

画饼


看到舍友们在复习数据库期末考试, 然后想到上学期学的时候对于事务以及并发这里学校并未怎么讲到.

然后学后端现在也开始进入到处理分布式,并发这些问题了.

先给自己挖一个数据库学习的坑吧.