携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
隔离
像各大编程语言保证临界区数据安全用锁,
那么mysql具体用啥子保证数据安全?下面给予介绍哈哈
1.重点简述
介绍流程图1.1
graph TD
MySQL事务隔离级别的概念与序列化隔离 -->
MySQL事务隔离级别可重复读-提交读和未提交读 -->
MySQL性能与非事务表的表锁定
c++锁介绍--> 3个线程轮流输出A,B,C
c++锁介绍--> 保护临界区
MySQL事务隔离级别的概念与序列化隔离
查看隔离级别: SELECT @@GLOBAL.tx_isolation ,@@session.tx_isolation
设置隔离级别: set SESSION TRANSACTION ISOLATION LEVEL serializable(XXX)
四种隔离级别
- serializable:序列化(或串行化)
全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
就是对事务操作进行排队,一个事务能执行当且仅当它前面没有事务等待。
2 repeatable read: 可重复读
在同一个事务内的查询都是事务开始时刻一致的
就是在同一个事务里面先后执行同一个查询语句的时候,得到的结果是一样的
3 read committed: 提交读
只能读取到已经提交的数据
4 read uncommitted: 未提交读
允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
并发情况下,读操作可能存在的三类问题:
- 脏读:当前事务(A)中可以读到其他事务(B)未提交的数据(脏数据),这种现象是脏读。
- 不可重复读:在事务A中先后两次读取同一个数据,两次读取的结果不一样,这种现象称为不可重复读。脏读与不可重复读的区别在于:前者读到的是其他事务未提交的数据,后者读到的是其他事务已提交的数据。
- 幻读:在事务A中按照某个条件先后两次查询数据库,两次查询结果的条数不同,这种现象称为幻读。不可重复读与幻读的区别可以通俗的理解为:前者是数据变了,后者是数据的行数变了。
锁
场景
10个线程同时对一个数(num)进行加操作,保证num的安全性
参考实现
#include <thread>
#include <iostream>
#include<mutex>
int num = 0;
std::mutex mutex;
void plus(){
std::lock_guard<std::mutex> guard(mutex);
std::cout << num++ <<std::endl;
}
int main(){
std::thread threads[10];
for (auto & i : threads) {
i = std::thread(plus);
}
for (auto & thread : threads) {
thread.join();
}
return 0;
}
条件变量
场景
3个线程轮流输出A,B,C
参考实现
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
int num = 0;
std::mutex mutex;
std::condition_variable cv;
std::thread t[3];
std::string s = "abc";
void run(int id){
for(int i=0;i<3;i++){
std::unique_lock<std::mutex> lock(mutex);
cv.wait(lock,[&]()->bool{
return id==num;
});
num=(num+1)%3;
std::cout<<s[id]<<" ";
cv.notify_all();
}
}
int main(){
for(int i=0;i<3;i++){
t[i]=std::thread(run,i);
}
for(int i=0;i<3;i++){
t[i].join();
}
return 0;
}