高并发时,数据一致性问题
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,确保把磁盘数据读到内存后再判断数据是否存在,不存在才能插入数据,否则报错,以此来保证数据是唯一的。
更改隔离级别为串行化,也能实现并发写入时数据唯一。