消息的幂等性


1 什么是消息的幂等性

如果同一个消息,因为各种原因,不慎被消费了多次(例如多次点按按钮),和只消费一次得到的数据是相同的。就可以说保持了幂等性。
如果我们不人为保证消息的幂等性,数据就会出错。可以通过乐观锁、悲观锁等方式保证消息的等幂性。

2 乐观锁与悲观锁

乐观锁是一种教宽松的锁机制,在线程进行数据更新之前对当前的数据版本进行比对,如果版本相同则允许进行操作。
悲观锁是一种较严格的锁机制,即悲观的认为每个线程在更新数据的时候都会被其他线程修改数据。为了防止这种情况,在一个线程需要操作数据时,先取锁再操作。

3 乐观锁

3.1 乐观锁之CAS

CAS即CompareAndSwap(比较和交换)。
当希望更新一条数据的时候,将原始的数据也一起取出来。最终进行更新的时候,将取出的原始数据和现在数据库中的数据进行比较,如果相同,则进行操作。
例如:数据库中有一条用户信息的用户名为Tom,需要变更为Tony。生产者在生产消息时,消息中就携带着原始的用户名Tom。当消费者进行更新操作前,将Tom和当前数据库中的用户名进行比较,
相同才进行更新操作。

3.2 CAS的缺点

虽然能够实现乐观锁,但CAS方式并不是完美的,也存在一些缺点。

ABA问题

还是以修改用户名为例,理想中的CAS流程是这样的:

而实际的流程却可能是这样的:

在取出数据与更新数据的间隔之间,数据已经被修改过了。
现实中的类似的情况就是,保险柜里有10W块钱。财务人员监守自盗,拿着10W元去买彩票。中奖之后又往保险柜里放了10W元。虽然前后金额没有变化,但却是存在安全隐患的。

3.3 乐观锁之版本号

版本号机制本质还是CAS,但通过给变量携带一个版本号,规避了ABA问题。
版本号可以使用一个自增的数字,也可以使用时间戳。

4 悲观锁

悲观锁主要依靠关系型数据库的锁机制。悲观锁又分为共享锁和排它锁。

4.1 共享锁

共享锁又称为读锁。多个事务可以共享一个读锁,对数据进行读取。

4.2 排它锁

排它锁又称为写锁。只有一个事务可以获取到写锁。其他事务要等待获取到写锁才可以对数据进行更新操作。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM