C++与数据库MySQL锁——模拟订票(事务)

假设订票的时候,好几个人同时进入,查看这张票是否售出,假如同时购买了这张票,那对于售票行业来说,可能就会发生低级错误。那么如何避免这类事情发生呢?

解决办法:

在一个人访问的时候,另外一个人不可以访问,将票锁住,锁完之后,再更新,让其他的线程来访问。

在C++/C中常见的锁分为两类:表锁,行锁

1、表锁:将整个表都锁柱,整张表都不可以访问 Innodb和MyISAM都可以

1.1、锁住表的读

其他人都不能读

cpp 复制代码
lock table t_vedio read;

1.2、锁住表的写

其他人都不可以写,但是可以读

cpp 复制代码
lock table t_vedio write;

1.2、解锁

cpp 复制代码
unlock tables;

但是,它的缺点就是:假定一张的表里面有很多张票,例如从北京到陕西,北京到甘肃,北京到上海等票都在一个库里面,这个时候,如果你将整个表锁住了,但是他们之间又米有竞争关系,起始就是浪费了资源,其他线程都必须等一个操作完成之后才能进入下一个。所以表锁在很多情况下是没必要的,但是,Innodb和MyISAM都支持表锁。而表锁只适用于Innodb,支持事务的rollback。

2、行锁(事务)

cpp 复制代码
select *from t_tickets XXX for update;

2.1、取票/查看票

cpp 复制代码
//取票
 my.StartTransaction();
cpp 复制代码
bool LXMysql::StartTransaction()
	{
		//有一个start Transaction的接口,只需要调用另外一个接口,也就是把自动提交

		return Query("set autocommit=0");
	}

2.2、锁住表

cpp 复制代码
select *from t_tickets where sold=0  order by id for update;

2.3、 购买这张票

10s之后这张票的状态置为1,也就是卖出了

cpp 复制代码
   //购买这张票
        //模拟冲突  3s过后更新这张票
        this_thread::sleep_for(10s);

2.4、更新表,将第一张票置为1,售出了,更新一下表

cpp 复制代码
//更新
        string id = rows[0][0].data;
        //取出第一行的id号  找到了这张票
        data["sold"] = "1";
        string where = "where id=";
        where += id;
        //更新成功
        cout << my.Update(data, "t_tickets", where) << endl;

2.5、提交事务

cpp 复制代码
     my.Commit();
        my.StopTransaction();
cpp 复制代码
bool LXMysql::StopTransaction()
	{
		return Query("set autocommit=1");
	}
	bool LXMysql::Commit()
	{
		return Query("commit");
	}

3、演示:

3.1、假设现在数据库里的表都没有售出:

3.2、现在进来两个人来买票,找到你的代码的exe文件

启动两次exe

当不使用行表的时候,一张票被两个人购买,

cpp 复制代码
select *from t_tickets where sold=0  order by id

使用行锁,起始也就是加了行锁for update;

根据时间顺序,购买不同的票,id=2的票被买走之后,顺次购买id=3的

cpp 复制代码
select *from t_tickets where sold=0  order by id for update;
相关推荐
JieE2128 小时前
LeetCode 101. 对称二叉树|JS 递归 + 迭代双解法,彻底搞懂镜像判断
javascript·算法
JieE2121 天前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack202 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树2 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
倔强的石头_2 天前
《Kingbase护城河》——数据库存储空间全景探测与精细化瘦身实战
数据库
云技纵横2 天前
唯一索引 INSERT 死锁实战:5 秒复现交叉插入的 S 锁循环等待
sql·mysql
沉默王二2 天前
面试官:RAG 不用向量数据库,用 MySQL 硬扛?我:100 万向量不是很轻松?
mysql·面试·ai编程
JieE2122 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2122 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
冬奇Lab2 天前
每日一个开源项目(第134篇):Zvec - 阿里开源的嵌入式向量数据库,向量搜索界的 SQLite
数据库·人工智能·llm