高并发时,数据一致性问题

高并发时,数据一致性问题

May 8, 2024
并发, 协程

对于共享资源,在多用户访问、程序内、数据库中,怎么保证共享资源独占,数据一致性。

分布式锁 #

分布式锁可以保证多用户独占资源。

读写锁 #

读写锁可以在程序内保证共享资源的临界

事务 #

事务可以解决mysql数据库的数据一致性

唯一索引 #

将一个字段加入唯一索引,可以避免重复数据

为什么唯一索引可以保证数据唯一? #

mysql作为数据库内部主要为 server层(连接管理->分析器->优化器->执行器)和存储引擎层(myISAM、InnoDB、MEMORY),
数据库读写不从磁盘直接读取,速度太慢,磁盘前面加一层内存(buffer pool),主要是使用双向链表,存放一个个数据页,每个默认16kb,
数据页存放的是磁盘的数据。一般插入、更新 放入change buffer后直接返回,异步更新数据页,再写回磁盘。
但是唯一索引要保证数据唯一,先看数据有无重复,无重复再插入或更新,性能上输了一大截。唯一索引会绕过change buffer ,
确保把磁盘数据读取到内存后再判断数据是否存在,不存在才会插入数据,否则报错,以此保证数据唯一。

串行隔离级别 #

事务们都是依次执行的,保证数据唯一,但是性能较差,
// 修改当前会话为串行化
SET SESSION  TRANSACTION ISOLATION LEVEL  SERIALIZABLE;

// 查看当前会话的事务隔离级别
select @@tx_isolation;
// 输出 SERIALIZABLE

// 查看全局事务隔离级别
select @@global.tx_isolation;
// 输出 REPEATABLE-READ

总结 #

加唯一索引可以保证数据并发写入时数据唯一,而且最省事省心。
数据库通过引入一层buffer pool内存来提升读写速度,普通索引可以利用change buffer提高数据插入的性能。
唯一索引会绕过change buffer,确保把磁盘数据读到内存后再判断数据是否存在,不存在才能插入数据,否则报错,以此来保证数据是唯一的。
更改隔离级别为串行化,也能实现并发写入时数据唯一。