分布式事务⾯试题(史上最全、持续更新、吐⾎推荐)
名词解释
事务:事务是由⼀组操作构成的可靠的独⽴的⼯作单元,事务具备ACID的特性,即原⼦性、⼀致性、隔离性和持久性。
本地事务:当事务由资源管理器本地管理时被称作本地事务。本地事务的优点就是⽀持严格的ACID特性,⾼效,可靠,状态可以只在资源管理器中维护,⽽且应⽤编程模型简单。但是本地事务不具备分布式事务的处理能⼒,隔离的最⼩单位受限于资源管理器。
phothy编程全局事务:当事务由全局事务管理器进⾏全局管理时成为全局事务,事务管理器负责管理全局的事务状态和参与的资源,协同资源的⼀致提交回滚。
TX协议:应⽤或者应⽤服务器与事务管理器的接⼝。
XA协议:全局事务管理器与资源管理器的接⼝。XA是由X/Open组织提出的分布式事务规范。该规范主要定义了全局事务管理器和局部资源管理器之间的接⼝。主流的数据库产品都实现了XA接⼝。XA接⼝是⼀个双向的系统接⼝,在事务管理器以及多个资源管理器之间作为通信桥梁。之所以需要XA是因为在分布式系统中从理论上讲两台机器是⽆法达到⼀致性状态的,因此引⼊⼀个单点进⾏协调。由全局事务
管理器管理和协调的事务可以跨越多个资源和进程。全局事务管理器⼀般使⽤XA⼆阶段协议与数据库进⾏交互。
AP:应⽤程序,可以理解为使⽤DTP(Data Tools Platform)的程序。
RM:资源管理器,这⾥可以是⼀个DBMS或者消息服务器管理系统,应⽤程序通过资源管理器对资源进⾏控制,资源必须实现XA定义的接⼝。资源管理器负责控制和管理实际的资源。
TM:事务管理器,负责协调和管理事务,提供给AP编程接⼝以及管理资源管理器。事务管理器控制着全局事务,管理事务的⽣命周期,并且协调资源。
两阶段提交协议:XA⽤于在全局事务中协调多个资源的机制。TM和RM之间采取两阶段提交的⽅案来解决⼀致性问题。两节点提交需要⼀个协调者(TM)来掌控所有参与者(RM)节点的操作结果并且指引这些节点是否需要最终提交。两阶段提交的局限在于协议成本,准备阶段的持久成本,全局事务状态的持久成本,潜在故障点多带来的脆弱性,准备后,提交前的故障引发⼀系列隔离与恢复难题。
BASE理论:BA指的是基本业务可⽤性,⽀持分区失败,S表⽰柔性状态,也就是允许短时间内不同步,E表⽰最终⼀致性,数据最终是⼀致的,但是实时是不⼀致的。原⼦性和持久性必须从根本上保障,为了可⽤性、性能和服务降级的需要,只有降低⼀致性和隔离性的要求。CAP定理:对于共享数
据系统,最多只能同时拥有CAP其中的两个,任意两个都有其适应的场景,真是的业务系统中通常是ACID与CAP的混合体。分布式系统中最重要的是满⾜业务需求,⽽不是追求⾼度抽象,绝对的系统特性。C表⽰⼀致性,也就是所有⽤户看到的数据是⼀样的。A表⽰可⽤性,是指总能到⼀个可⽤的数据副本。P表⽰分区容错性,能够容忍⽹络中断等故障。
分布式事务与分布式锁的区别:
分布式锁解决的是分布式资源抢占的问题;分布式事务和本地事务是解决流程化提交问题。
事务简介
事务(Transaction)是操作数据库中某个数据项的⼀个程序执⾏单元(unit)。
事务应该具有4个属性:原⼦性、⼀致性、隔离性、持久性。这四个属性通常称为ACID特性。
事务的四个特征:
1、Atomic原⼦性
事务必须是⼀个原⼦的操作序列单元,事务中包含的各项操作在⼀次执⾏过程中,要么全部执⾏成功,要么全部不执⾏,任何⼀项失败,整个事务回滚,只有全部都执⾏成功,整个事务才算成功。
2、Consistency⼀致性
事务的执⾏不能破坏数据库数据的完整性和⼀致性,事务在执⾏之前和之后,数据库都必须处于⼀致性状态。
3、Isolation隔离性
在并发环境中,并发的事务是相互隔离的,⼀个事务的执⾏不能被其他事务⼲扰。即不同的事务并发操纵相同的数据时,每个事务都有各⾃完整的数据空间,即⼀个事务内部的操作及使⽤的数据对其他并发事务是隔离的,并发执⾏的各个事务之间不能相互⼲扰。
SQL中的4个事务隔离级别:
手工教程(1)读未提交
允许脏读。如果⼀个事务正在处理某⼀数据,并对其进⾏了更新,但同时尚未完成事务,因此事务没有提交,与此同时,允许另⼀个事务也能够访问该数据。例如A将变量n从0累加到10才提交事务,此时B可能读到n变量从0到10之间的所有中间值。
(2)读已提交
允许不可重复读。只允许读到已经提交的数据。即事务A在将n从0累加到10的过程中,B⽆法看到n的中间值,之中只能看到10。同时有事务C进⾏从10到20的累加,此时B在同⼀个事务内再次读时,读到的是20。
(3)可重复读
允许幻读。保证在事务处理过程中,多次读取同⼀个数据时,其值都和事务开始时刻时是⼀致的。禁⽌脏读、不可重复读。幻读即同样的事务操作,在前后两个时间段内执⾏对同⼀个数据项的读取,可能出现不⼀致的结果。保证B在同⼀个事务内,多次读取n的值,读到的都是初始值0。幻读,就是不同事务,读到的n的数据可能是0,可能10,可能是20
(4)串⾏化
最严格的事务,要求所有事务被串⾏执⾏,不能并发执⾏。
如果不对事务进⾏并发控制,我们看看数据库并发操作是会有那些异常情形
(1)⼀类丢失更新:两个事物读同⼀数据,⼀个修改字段1,⼀个修改字段2,后提交的恢复了先提交修改的字段。
数据库管理系统中对数据信息的操作特点(2)⼆类丢失更新:两个事物读同⼀数据,都修改同⼀字段,后提交的覆盖了先提交的修改。
(3)脏读:读到了未提交的值,万⼀该事物回滚,则产⽣脏读。
(4)不可重复读:两个查询之间,被另外⼀个事务修改了数据的内容,产⽣内容的不⼀致。
(5)幻读:两个查询之间,被另外⼀个事务插⼊或删除了记录,产⽣结果集的不⼀致。
4、Durability持久性
持久性(durability):持久性也称永久性(permanence),指⼀个事务⼀旦提交,它对数据库中对应数据的状态变更就应该是永久性的。
即使发⽣系统崩溃或机器宕机,只要数据库能够重新启动,那么⼀定能够将其恢复到事务成功结束时的状态。
⽐⽅说:⼀个⼈买东西的时候需要记录在账本上,即使⽼板忘记了那也有据可查。
MySQL的本地事务实现⽅案
⼤多数场景下,我们的应⽤都只需要操作单⼀的数据库,这种情况下的事务称之为本地事务(Local Transaction)。本地事务的ACID特性是数据库直接提供⽀持。
了解过MySQL事务的同学,就会知道,为了达成本地事务,MySQL做了很多的⼯作,⽐如回滚⽇志,重做⽇志,MVCC,读写锁等。
MySQL数据库的事务实现原理
以MySQL 的InnoDB (InnoDB 是 MySQL 的⼀个存储引擎)为例,介绍⼀下单⼀数据库的事务实现原理。
InnoDB 是通过 ⽇志和锁 来保证的事务的 ACID特性,具体如下:
(1)通过数据库锁的机制,保障事务的隔离性;
(2)通过 Redo Log(重做⽇志)来,保障事务的持久性;
log4j漏洞挖掘(3)通过 Undo Log (撤销⽇志)来,保障事务的原⼦性;
(4)通过 Undo Log (撤销⽇志)来,保障事务的⼀致性;
Undo Log 如何保障事务的原⼦性呢?
具体的⽅式为:在操作任何数据之前,⾸先将数据备份到⼀个地⽅(这个存储数据备份的地⽅称为 Un
do Log),然后进⾏数据的修改。如果出现了错误或者⽤户执⾏了 Rollback 语句,系统可以利⽤ Undo Log 中的备份将数据恢复到事务开始之前的状态。
Redo Log如何保障事务的持久性呢?
具体的⽅式为:Redo Log 记录的是新数据的备份(和 Undo Log 相反)。在事务提交前,只要将 Redo Log 持久化即可,不需要将数据持久化。当系统崩溃时,虽然数据没有持久化,但是 Redo Log 已经持久化。系统可以根据 Redo Log 的内容,将所有数据恢复到崩溃之前的状态。
脏读、幻读、不可重复读
在多个事务并发操作时,数据库中会出现下⾯三种问题:脏读,幻读,不可重复读。
脏读(Dirty Read)
事务A读到了事务B还未提交的数据:
事务A读取的数据,事务B对该数据进⾏修改还未提交数据之前,事务A再次读取数据会读到事务B已经修改后的数据,如果此时事务B进⾏回滚或再次修改该数据然后提交,事务A读到的数据就是脏数据,这个情况被称为脏读(Dirty Read)。
img
幻读(Phantom Read)
事务A进⾏范围查询时,事务B中新增了满⾜该范围条件的记录,当事务A再次按该条件进⾏范围查询,会查到在事务B中提交的新的满⾜条件的记录(幻⾏ Phantom Row)。
img
不可重复读(Unrepeatable Read)
事务A在读取某些数据后,再次读取该数据,发现读出的该数据已经在事务B中发⽣了变更或删除。
img
mysql面试题acid幻读和不可重复度的区别:
幻读:在同⼀事务中,相同条件下,两次查询出来的 记录数 不⼀样;
不可重复读:在同⼀事务中,相同条件下,两次查询出来的 数据 不⼀样;
事务的隔离级别
为了解决数据库中事务并发所产⽣的问题,在标准SQL规范中,定义了四种事务隔离级别,每⼀种级别都规定了⼀个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的。
低级别的隔离级⼀般⽀持更⾼的并发处理,并拥有更低的系统开销。
通过修改MySQL系统参数来控制事务的隔离级别,在MySQL8中该参数为 transaction_isolation ,在MySQL5中该参数为 tx_isolation :
MySQL8:
generic storage device– 查看系统隔离级别:
SELECT @@ansaction_isolation;
– 查看当前会话隔离级别
SELECT @@transaction_isolation;
– 设置当前会话事务隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
– 设置全局事务隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
事务的四个隔离级别:
未提交读(READ UNCOMMITTED):所有事务都可以看到其他事务未提交的修改。⼀般很少使⽤;
提交读(READ COMMITTED):Oracle默认隔离级别,事务之间只能看到彼此已提交的变更修改;
可重复读(REPEATABLE READ):MySQL默认隔离级别,同⼀事务中的多次查询会看到相同的数据⾏;可以解决不可重复读,但可能出现幻读;
可串⾏化(SERIALIZABLE):最⾼的隔离级别,事务串⾏的执⾏,前⼀个事务执⾏完,后⾯的事务会执⾏。读取每条数据都会加锁,会导致⼤量的超时和锁争⽤问题;
img
问:如何保证 REPEATABLE READ 级别绝对不产⽣幻读?
答:在SQL中加⼊ for update (排他锁) 或 lock in share mode (共享锁)语句实现。就是锁住了可能造成
幻读的数据,阻⽌数据的写⼊操作。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论