数据库之 深入理解 单机事务

编程入门 行业动态 更新时间:2024-10-24 13:26:20

数据库之 深入理解 <a href=https://www.elefans.com/category/jswz/34/1750147.html style=单机事务"/>

数据库之 深入理解 单机事务

ACID的传统解释,我去百度一个,贴在这里放在:

 

ACID是事务的四大特性,想要成为事务,必须具备这四点。

Atomicity
原子性体现在对于一个事务来讲,要么一起执行成功要么一起失败,执行的过程中是不能被打断或者执行其他操作的。

Consistency
一致性表现为事务进行过后和执行前,整体系统都是稳定的,比如对于入账出账操作是不会有总资金的变化的。

Isolation
隔离性表示各个事务之间不会互相影响,数据库一般会提供多种级别的隔离。实际上多个事务是并发执行的,但是他们之间不会互相影响。

Durability
持久性表示一旦一个事务成功了,那么他的改变是永久性的被记录和操作。
 

下面是一些具体的心得解释:比上面的深刻得多得多

 

1、原子性

一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

举例说明:

bob 给smith转账100元,事务分解为三个操作,分别对应v1,v2和v3。 


两个状态 事务的初始状态对应v1.    事物的最终状态 执行成功则为v3,失败则只能回滚到v1状态。

原子性只保证记录回滚段。如果在v3步发现smith账户不存在或者在v3步 smith的100块也加上了但commit失败。

则会通过回滚段回滚至事务的初始状态。具体是先通过v3 执行v3的undo 将状态 回退至 v2状态。然后v2再通过v2

的undo回退至v1状态。

对于中间状态v2  原子性并不保证你看不到中间状态。在一致性(C)不保证的前提下。另如有别的线程在v2时  给smith增加了300元。但是该事务在v3时出错导致回滚值事务的最初状态 。 那么 smith的这300块 就平白无故的 消失了。因为这里是原子性所以他不保证一致性,数据丢失就丢失了,所以才有了下面的一致性.

原子性的语意只保证记录回滚段(Undo日志)。通过回滚段可以回滚到之前的版本。其他的不做任何保证。

2、一致性

一般来说 原子性操作 都需要考虑一致性的问题。一致性的核心就是Can(happen before)(个人觉得其实和java中的多线程的happen before  概念非常类似)。就是一个事务单元全部执行成功才可见。

事务单元与事务单元之间并发执行的时候可能在视点3 对Bob 或Smith进行更新操作。当事务回滚时会导致视点3的更新丢失。这个是严重的问题,如上面原子性讲到的smith 平白无故少了300元钱。 一致性保证happen beofre关系,就是在事务单元的开始和结束分别进行加锁和解锁 的操作。正式由于此强一致性 是的事务的视点3被迫 移到视点1的位置。这样做实际上就是对所有的事务进行排队的过程(实际过程很复杂)。 就是串行化了,效率很低了.

 

3、隔离性

如果一个事务结束,另一个事物才能进来  那么系统肯定是一致性的。但是完全一致性的情况下,定会导致系统的并发运行效率低。 于是不得不使用隔离性 提高系统的并发度。

隔离性 就是 以性能为理由,对一致性的破坏

数据库事务的隔离级别有4个,由高到低依次为Serializable、Repeatable read、Read committed、Read uncommitted。


(1)Serializable序列化读写  (队列  排它锁 )

将所有的请求排队,用排它锁把事务单元锁住。单位时间内只有一个‘人’能进来。全部是是串行,性能差导致系统不可用。

读写锁的隔离级别  Repeatable read 可重复读 和 Read committed 读已提交和 Read uncommitted 读未提交

(2)Repeatable read可重复读   (读锁不能被写锁升级,只能读读并行,并不能完美提升性能。)

(3) Read committed读已提交(读锁可以被写锁升级  ,可以实现   读读并行、读写并行

在Read committed读已提交时会出现  不可重复读 。同一事务的两次读到的结果可能不一致。因为在前一次读后,另一个写操作执行写提交。再读的话就会导致两次读结果不一致。而Repeatable read可重复读 是读读并行,不会出现  这种问题。

 (4)Read uncommitted读未提交    只加写锁,不加读锁。可以做到读读并行、读写并行、写读并行 

可以做到读读并行、读写并行、写读并行 。写写只能串行。

代价:

读到一些未提交的中间状态数据 ,因为读没加锁。所以一般不使用这种隔离级别。

 

为了提高并行性,我们要解决读读,读写,写读,写写四个问题.

 

到这里了就有一个问题了,我们已经实现了读读,读写,写读的并行了,有没有办法实现写写的并行呢?解决了,这个所有的操作都可以实现并行,数据库的性能将得到飞的提升哦....

 

SQL92标准出来后,又出来个新的模式,快照隔离级别MVCC,并不属于这上面的几种,

他是一种新的方式实现传统意义上的杜伟提交的场景,同时保证可序列化的隔离级别.代价:如何写多与读,会增加系统成本

他就是解决了读读,读写,写读,类似于一致性中的视点3,把这个视点3提升到了视点1的位置,解决了写读的问题....

MVCC比较适合读写比率比较高的情况.

 

 

4、持久性(Durability)


指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。

只要事务提交完成就必须保证数据保存下来了,传统使用的是 RAID的持久性

遇到的问题有? 

1.磁盘的物理损坏

2.数据->内存  内存数据易丢失

3.每次commit都要fsync到磁盘,系统性能的下降

持久性    延迟    的取舍

 

一块磁盘不够就两块磁盘,保证同时成功或者同时失败...

 

1.提交请求到内存返回

2.将内存的数据打包到磁盘

组提交,一起提交...(这样就进一步提升了延迟)这里就涉及到了 两个之间的协调问题了

 

 

核心目的:  提升并行度,这个在计算机中普遍存在,cpu和内存的关系啊,内存与磁盘的关系....

 


 

5.多个事务并发时的并发问题:

•脏读:一个事务读到另一事务未提交的更新数据。

•不可重复读:一个事务读到另一事务已提交的更新数据。

•虚读:一个事务读到另一事务已提交的新插入的数据。

•第一类丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖。

•第二类丢失更新:这是不可重复读中的特例,一个事务覆盖另一事务已提交的更新数据。


数据库事务的隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,

这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。
 


 

注意:我们讨论隔离级别的场景,主要是在多个事务并发的情况下,因此,接下来的讲解都围绕事务并发。

Read uncommitted 读未提交  (读读   读写  写读并行)
公司发工资了,领导把5000元打到singo的账号上,但是该事务并未提交,而singo正好去查看账户,发现工资已经到账,是5000元整,非常高兴。可是不幸的是,领导发现发给singo的工资金额不对,是2000元,于是迅速回滚了事务,修改金额后,将事务提交,最后singo实际的工资只有2000元,singo空欢喜一场。
 

 

出现上述情况,即我们所说的脏读,两个并发的事务,“事务A:领导给singo发工资”、“事务B:singo查询工资账户”,事务B读取了事务A尚未提交的数据。

当隔离级别设置为Read uncommitted时,就可能出现脏读,如何避免脏读,请看下一个隔离级别。

Read committed 读提交   (读读   读写并行)
singo拿着工资卡去消费,系统读取到卡里确实有2000元,而此时她的老婆也正好在网上转账,把singo工资卡的2000元转到另一账户,并在singo之前提交了事务,当singo扣款时,系统检查到singo的工资卡已经没有钱,扣款失败,singo十分纳闷,明明卡里有钱,为何......

出现上述情况,即我们所说的不可重复读,两个并发的事务,“事务A:singo消费”、“事务B:singo的老婆网上转账”,事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。

当隔离级别设置为Read committed时,避免了脏读,但是可能会造成不可重复读。

大多数数据库的默认级别就是Read committed,比如Sql Server , Oracle。如何解决不可重复读这一问题,请看下一个隔离级别。

Repeatable read 重复读 (读读并行)
当隔离级别设置为Repeatable read时,可以避免不可重复读。当singo拿着工资卡去消费时,一旦系统开始读取工资卡信息(即事务开始),singo的老婆就不可能对该记录进行修改,也就是singo的老婆不能在此时转账。

虽然Repeatable read避免了不可重复读,但还有可能出现幻读。

singo的老婆工作在银行部门,她时常通过银行内部系统查看singo的信用卡消费记录。有一天,她正在查询到singo当月信用卡的总消费金额(select sum(amount) from transaction where month = 本月)为80元,而singo此时正好在外面胡吃海塞后在收银台买单,消费1000元,即新增了一条1000元的消费记录(insert transaction ... ),并提交了事务,随后singo的老婆将singo当月信用卡消费的明细打印到A4纸上,却发现消费总额为1080元,singo的老婆很诧异,以为出现了幻觉,幻读就这样产生了。

注:Mysql的默认隔离级别就是Repeatable read。

Serializable 序列化
Serializable是最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻像读
 

 

/*** 单机事务异常的对应策略:*  *  回滚日志  加锁不要正在回滚的数据,保证数据的一致性* * 系统Down机了* 事务的原子性操作只有一个标记commit* commit完成后,之后的请求必须正常的完成** 重启后进入recovery模式,提交后事务单元继续完成提交,未提交事务单元回滚.* recovery模式也是原子性操作,必须ACID.* 当recovery时,也挂了....记录日志,保证不会数据丢失*** 事务调优* 尽可能减少锁的覆盖范围*     Myisam表锁  ->  innodb行锁**     MVCC也是减少锁的范围** 增加锁上的可并行的线程数*      读锁写锁分离,允许并行读取数据*      多线程并行读取** 选择正确的锁的类型*     悲观锁:使线程到blocking状态,并发争抢比较严重的场景*        通知信息ok的状态切换回等待状态*        换入换出*     乐观锁: 适合并发争抢不太严重的场景***/

 

 

这篇博客有一部分来自于 ,一部分自己扩充

更多推荐

数据库之 深入理解 单机事务

本文发布于:2024-02-11 20:54:23,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1683417.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:单机   事务   数据库

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!