什么是事物?
事务就是提供一种“要么什么都不做,要么做全套(All or Nothing)”机制。
数据库事务中的四大特性 ACID你是怎么理解的?
A:原子性(Atomicity):你买东西要么交钱收货一起都执行,要么发不出货,就退钱。
一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。
事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
C:一致性(Consistency):你买东西,买之前和买之后东西是一样的,如果在买的过程,你不给钱,老板就把东西收回放到原来位置。
事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。
如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。
如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。
I:隔离性(Isolation):你买东西这个事情,是不影响其他人的。
指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。
由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。
D:持久性(Durability):你买东西的时候需要记录在账本上,即使老板忘记了那也有据可查。
指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。
即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。
数据库事务的异常情况?
数据库在提交事务的时候突然断电,那么它是怎么样恢复的呢?
本地事务数据库断电的这种情况,它是怎么保证数据一致性的呢?我们使用SQL Server来举例,我们知道我们在使用 SQL Server 数据库是由两个文件组成的,一个数据库文件和一个日志文件,通常情况下,日志文件都要比数据库文件大很多。数据库进行任何写入操作的时候都是要先写日志的,同样的道理,我们在执行事务的时候数据库首先会记录下这个事务的redo操作日志,然后才开始真正操作数据库,在操作之前首先会把日志文件写入磁盘,那么当突然断电的时候,即使操作没有完成,在重新启动数据库时候,数据库会根据当前数据的情况进行undo回滚或者是redo前滚,这样就保证了数据的强一致性。
为什么要提到这个知识点呢? 因为分布式系统的核心就是处理各种异常情况,这也是分布式系统复杂的地方,因为分布式的网络环境很复杂,这种“断电”故障要比单机多很多,所以我们在做分布式系统的时候,最先考虑的就是这种情况。这些异常可能有 机器宕机、网络异常、消息丢失、消息乱序、数据错误、不可靠的TCP、存储数据丢失、其他异常等等...
什么是分布式事物?
一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。分布式事务就是为了保证不同数据库的数据一致性。
分布式事物是怎么产生的?
实际情况分析:
当我们的单个数据库的性能产生瓶颈的时候,我们可能会对数据库进行分区,这里所说的分区指的是物理分区,分区之后可能不同的库就处于不同的服务器上了,这个时候单个数据库的ACID已经不能适应这种情况了,而在这种ACID的集群环境下,再想保证集群的ACID几乎是很难达到,或者即使能达到那么效率和性能会大幅下降,最为关键的是再很难扩展新的分区了,这个时候如果再追求集群的ACID会导致我们的系统变得很差,这时我们就需要引入一个新的理论原则来适应这种集群的情况,就是 CAP 原则或者叫CAP定理,那么CAP定理指的是什么呢?
CAP定理:
C:强一致性——在很高强度下保持数据一致,对某个指定的客户端来说,读操作能返回最新的写操作。
A:高可用性——在并发量很高情况下依然可用,非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。可用性的两个关键一个是合理的时间,一个是合理的响应。合理的时间指的是请求不能无限被阻塞,应该在合理的时间给出返回。合理的响应指的是系统应该明确返回结果并且结果是正确的。
P:分区容错性——整个系统中某个组件故障时整个系统仍然可用而不是崩溃,比如这里集群有多台机器,有台机器网络出现了问题,但是这个集群仍然可以正常工作。
注意:三者不能共有,如果感兴趣可以搜索 CAP 的证明,在分布式系统中,网络无法 100% 可靠,分区其实是一个必然现象。P必须保证。C和A之间二选一。因为要做到强一致性,需要在必要的地方加数据锁,必然会影响性能。
CP
AP
案例:
案例1:一个公司之内,用户的资产可能分为好多个部分,比如余额,积分,优惠券等等,在公司内部有可能积分功能由一个微服务团队维护,优惠券又是另外的团队维护,这样的话就无法保证积分扣减了之后,优惠券能否扣减成功。
案例2:对于一个支付宝的转账业务来说,你给朋友转钱,有可能你的数据库是在北京,而你的朋友的钱是存在上海,所以我们依然无法保证他们能同时成功。
分布式事务的两种解决方法:
1 补偿性策略,在服务执行失败时,不进行回滚,因为一旦回滚,其他子系统的数据也要跟着更新改变,不利于维护,所以重复执行某个失败的业务,如果数次不成功,发送系统信息,短信,以及服务器日志,后期通过人工处理该异常订单
2 在消息中间件中启用消息事务,当一个消息消费失败时,回滚该消息,等待重新消费。可以参考消息队列章节。