悲观锁&乐观锁

6 篇文章 0 订阅
悲观锁(Pessimistic Lock)

悲观锁的特点是先获取锁,再进行业务操作,即“悲观”的认为获取锁是非常有可能失败的,因此要先确保获取锁成功再进行业务操作。通常所说的“一锁二查三更新”即指的是使用悲观锁。通常来讲在数据库上的悲观锁需要数据库本身提供支持,即通过常用的select … for update操作来实现悲观锁。当数据库执行select for update时会获取被select中的数据行的行锁,因此其他并发执行的select for update如果试图选中同一行则会发生排斥(需要等待行锁被释放),因此达到锁的效果。select for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用。

这里需要注意的一点是不同的数据库对select for update的实现和支持都是有所区别的,例如oracle支持select for update no wait,表示如果拿不到锁立刻报错,而不是等待,mysql就没有no wait这个选项。另外mysql还有个问题是select for update语句执行中所有扫描过的行都会被锁上,这一点很容易造成问题。因此如果在mysql中用悲观锁务必要确定走了索引,而不是全表扫描

乐观锁(Optimistic Lock)

乐观锁的特点先进行业务操作,不到万不得已不去拿锁。即“乐观”的认为拿锁多半是会成功的,因此在进行完业务操作需要实际更新数据的最后一步再去拿一下锁就好。

乐观锁在数据库上的实现完全是逻辑的,不需要数据库提供特殊的支持。一般的做法是在需要锁的数据上增加一个版本号,或者时间戳,

Demo:

表结构:

CREATE TABLE `goods` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
  `name` varchar(64) DEFAULT NULL COMMENT '商品名称',
  `count` int(11) DEFAULT NULL COMMENT '商品数量',
  `price` float DEFAULT NULL COMMENT '商品价格',
  `version` int(11) DEFAULT NULL COMMENT '数据版本号',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8


悲观锁(php 实现):

<?php
date_default_timezone_set('Asia/Shanghai');
$db = new mysqli('127.0.0.1','root','792a1d086a2b0a5d','test',3306);
$bugNum = 3;
$lockSql = "LOCK TABLE `goods` WRITE";
$unLockSql = "UNLOCK TABLES";
$lockRes = $db->query($lockSql);
if (!$lockRes) {
    echo "商品表锁定失败\n";	
} else {
    echo "商品表锁定成功\n";	
}
$sql = "select * from goods where id = 1";
$res = $db->query($sql);
while($value = $res->fetch_assoc()) {
    $curNum = $value['count'];
	if ($curNum < $bugNum) {
	    echo "商品库存不足\n";
	} else {
	    $curNum = $curNum - $bugNum;
		$updateSql = "update `goods` set count = " . $curNum . " where id = 1";
		echo $updateSql . "\n";
		$updateRes = $db->query($updateSql);
		if (!$updateRes) {
		    echo "商品去库存失败\n";	
		} else {
		    echo "商品去库存成功\n";	
		}
	}
}
sleep(20);
$unLockRes = $db->query($unLockSql);
if (!$unLockRes) {
	echo "商品表解锁失败\n";
} else {
    echo "商品表解锁成功\n";	
}
$db->close();

乐观锁(php实现):


<?php
date_default_timezone_set('Asia/Shanghai');
$db = new mysqli('127.0.0.1','root','792a1d086a2b0a5d','test',3306);
$buyNum = 3;
$sql = "select * from goods where id = 1";
$res = $db->query($sql);
while($value = $res->fetch_assoc()) {
    $curNum = $value['count'];
	$curVersion = $value['version'];
	if ($curNum < $buyNum) {
	    echo "商品库存不足\n";
	} else {
	    $curNum = $curNum - $buyNum;
		$nextVersion = $curVersion + 1;
		$updateSql = "update `goods` set count = " . $curNum . " and version = " . $nextVersion . " where id = 1 and version = " . $curVersion;
		echo $updateSql . "\n";
		$updateRes = $db->query($updateSql);
		if (!$updateRes) {
		    echo "数据过期,商品去库存失败\n";	
		} else {
		    echo "商品去库存成功\n";	
		}
	}
}
sleep(10);
$db->close();





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的体育馆管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本体育馆管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此体育馆管理系统利用当下成熟完善的SpringBoot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线选择试题并完成答题,在线查看考核分数。管理员管理收货地址管理、购物车管理、场地管理、场地订单管理、字典管理、赛事管理、赛事收藏管理、赛事评价管理、赛事订单管理、商品管理、商品收藏管理、商品评价管理、商品订单管理、用户管理、管理员管理等功能。体育馆管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:体育馆管理系统;SpringBoot框架;Mysql;自动化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值