当前位置: 首页 > news >正文

rails网站开发如何写营销软文

rails网站开发,如何写营销软文,网站建设的发展序列,领动做的网站怎么样一、首先来说一下什么是共享锁?什么是排他锁? 共享:我可以读 写 加锁 , 别人可以 读 加锁。 排他:只有我 才 可以 读 写 加锁 , 也就是说,必须要等我提交事务,其他的才可以操作。 二、简单例子实现加锁 锁…

 一、首先来说一下什么是共享锁?什么是排他锁?

共享:我可以  加锁 , 别人可以  加锁
排他:只有我 才 可以   加锁 , 也就是说,必须要等我提交事务,其他的才可以操作。

二、简单例子实现加锁

 锁和事务在使用时需要配合使用,也就是用锁时需要先开启事务,事务提交时,会自动解锁。

 DB::beginTransaction(); // 开启事务$good = \App\Models\Good::sharedLock()->first(); //共享锁 s锁 读锁 
// $good = \App\Models\Good::lockForUpdate()->first(); //排他锁 x锁 写锁...DB::commit();  
DB::beginTransaction();
$goodsInfo = Goods::where('goods_id',$gid)->lockForUpdate()->first();
$goodsInfo->seckill_stock-=1;
$goodsInfo->save();
DB::commit();

三、怎样利用锁和事务解决并发问题?

在我们的工作中,常常会出现一些对数量控制有精确要求的需求,比如商品库存量、奖品数量、报名人数限制等等,这些应用场景往往都存在高并发可能,比较容易出现数据量超量问题。以下做一下示例探索:

(1)首先设计一个存量表
CREATE TABLE `product` (`id` int(11) NOT NULL AUTO_INCREMENT,`product_name` varchar(255) NOT NULL DEFAULT '',`count` int(10) NOT NULL DEFAULT '0',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
(2)添加一行数据如下,设定基础库存量为 10

(3)问题代码如下:
        $process_num = 50; //开50个进程,模拟50个用户for ($i = 0; $i < $process_num; $i++) {MultiProcessHelper::instance($process_num)->multiProcessTask(function () use ($i) {if (Db::name('product')->where('id', 1)->value('count') > 0) {$res = Db::name('product')->where('id', 1)->setDec('count');if ($res) {dump('获取到更新资源权限:' . $i);}}});}

执行结果,50 个用户都获取到了更新资源的权限,但是数据库相应数据存量变成了 - 40

高并发带来的问题,同一时刻有多个进程读取同一条数据,同一时刻有多个进程更新同一条数据

(4)解决方案
1.方案1

要进行 DML 层面的限制(最后关卡安全,报错总比出现数据问题产生的影响小),主要的修改是将 count 的类型改成了无符号整数,这样该值就不可能再出现负数值

CREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_name` varchar(255) NOT NULL DEFAULT '',
`count` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

执行一下代码,当 count 值从 10 减到 0 时,就不能再减少了,再减就会出现数据库报错

2.方案2

mysql 提供的行级锁 select ... lock in share mode(阻塞写),select ... for update(阻塞读写,悲观锁),所以 for update 机制能满足我们的原子要求。编辑代码如下:

        $process_num = 50; //开50个进程,模拟50个用户for ($i = 0; $i < $process_num; $i++) {MultiProcessHelper::instance($process_num)->multiProcessTask(function () use ($i) {Db::startTrans(); //行级锁必须在事务中才能生效//设置for update,进程会阻塞在这里,只能允许一个进程获取到行锁,其他等待获取if (Db::name('product')->where('id', 1)->lock('for update')->value('count') > 0) { $res = Db::name('product')->where('id', 1)->setDec('count');if ($res) {dump('获取到更新资源权限:' . $i);}}Db::commit();});}

只有十个进程获取到了更新权限,消费正常

3.方案3

将条件语句放到 update 上,保持语句执行的原子性,杜绝并发幻读
修改代码如下:

    $process_num = 50; //开50个进程,模拟50个用户for ($i = 0; $i < $process_num; $i++) {MultiProcessHelper::instance($process_num)->multiProcessTask(function () use ($i) {//合并两条语句为一条更新语句$res = Db::name('product')->where('id', 1)->where('count', '>', 0)->setDec('count');if ($res) {dump('获取到更新资源权限:' . $i);}});}

只有十个进程获取到了更新权限,消费正常

4.方案4

文件锁机制解决

        $process_num = 50; //开50个进程,模拟50个用户for ($i = 0; $i < $process_num; $i++) {MultiProcessHelper::instance($process_num)->multiProcessTask(function () use ($i) {$filename = app()->getRootPath() . 'runtime/lock';$file = fopen($filename, 'w'); //打开文件$lock = flock($file, LOCK_EX);// $lock=flock($handle, LOCK_EX|LOCK_NB); (异步非阻塞,所有进程如果出现获取不到锁,不等待跳过,加锁失败)//获取文件排他锁:LOCK_EX(异步阻塞,只有一个进程获得锁,其他竞争进程等待)//还有一种共享锁:LOCK_SH(所有进程都可以获取共享锁,读取文件,当且只有一个锁时,才允许写操作,否则操作失败,容易出现死锁问题)if ($lock) {try {if (Db::name('product')->where('id', 1)->lock('for update')->value('count') > 0) {$res = Db::name('product')->where('id', 1)->setDec('count');if ($res) {dump('获取到更新资源权限:' . $i);}}} catch (\Exception $e) {dump($e->getMessage());} finally {flock($file, LOCK_UN); //无论如何都要释放锁}}fclose($file); //关闭文件句柄});}

只有十个进程获取到了更新权限,消费正常

5.方案5

分布式锁机制解决

以上文件锁,只适应于单体架构的需求,在集群架构、分布式等多机联网结构中就是掩耳盗铃了,所以适应性更好地锁机制还是要使用分布式锁,分布式锁最常用和最易用就是 redis 的 setnx 锁了。

        $process_num = 50; //开50个进程,模拟50个用户for ($i = 0; $i < $process_num; $i++) {MultiProcessHelper::instance($process_num)->multiProcessTask(function () use ($i) {//获取redis锁//关于CacheHelper::getRedisLock是怎样获取锁的,注意几个点就行:1.如何避免死锁;2.如何设置过期时间;3.如何设置抢占条件;4.如何循环等待判断。这些不在本文讨论范围,可自行研究,以后有空我也可以写一篇博文$lock = CacheHelper::getRedisLock('redis_lock');if ($lock) {try {if (Db::name('product')->where('id', 1)->lock('for update')->value('count') > 0) {$res = Db::name('product')->where('id', 1)->setDec('count');if ($res) {dump('获取到更新资源权限:' . $i);}}} catch (\Exception $e) {dump($e->getMessage());}} else {
//                    dump('获取redis锁失败');}});}

参考链接:浅谈并发加锁 | Laravel China 社区 (learnku.com)


文章转载自:
http://phycoerythrin.c7510.cn
http://vistaed.c7510.cn
http://lateral.c7510.cn
http://keef.c7510.cn
http://crowstep.c7510.cn
http://dekaliter.c7510.cn
http://epiphyte.c7510.cn
http://resediment.c7510.cn
http://civies.c7510.cn
http://macroevolution.c7510.cn
http://suberization.c7510.cn
http://lissome.c7510.cn
http://imbecility.c7510.cn
http://virosis.c7510.cn
http://pleasureless.c7510.cn
http://singer.c7510.cn
http://diphtheria.c7510.cn
http://hypocotyl.c7510.cn
http://papmeat.c7510.cn
http://unbearably.c7510.cn
http://goliath.c7510.cn
http://hemofuscin.c7510.cn
http://repassage.c7510.cn
http://mouthiness.c7510.cn
http://gag.c7510.cn
http://condign.c7510.cn
http://workaday.c7510.cn
http://dixy.c7510.cn
http://tho.c7510.cn
http://malformation.c7510.cn
http://alfalfa.c7510.cn
http://quotient.c7510.cn
http://bacat.c7510.cn
http://catchpenny.c7510.cn
http://autogeny.c7510.cn
http://curvicaudate.c7510.cn
http://euphonic.c7510.cn
http://cobaltous.c7510.cn
http://seaworthy.c7510.cn
http://abusage.c7510.cn
http://hepatocarcinogen.c7510.cn
http://auric.c7510.cn
http://displume.c7510.cn
http://afterburner.c7510.cn
http://arethusa.c7510.cn
http://compactible.c7510.cn
http://cobaltite.c7510.cn
http://androphile.c7510.cn
http://albumose.c7510.cn
http://gymnasium.c7510.cn
http://hyperpolarize.c7510.cn
http://intergeneric.c7510.cn
http://balmy.c7510.cn
http://zayin.c7510.cn
http://zamarra.c7510.cn
http://praties.c7510.cn
http://cystourethrography.c7510.cn
http://byron.c7510.cn
http://zincy.c7510.cn
http://locket.c7510.cn
http://cronk.c7510.cn
http://underdevelopment.c7510.cn
http://landwind.c7510.cn
http://entrancing.c7510.cn
http://ignace.c7510.cn
http://bedevilment.c7510.cn
http://platinum.c7510.cn
http://indecent.c7510.cn
http://windowy.c7510.cn
http://expurgatorial.c7510.cn
http://lisztian.c7510.cn
http://beerburst.c7510.cn
http://dominie.c7510.cn
http://crossly.c7510.cn
http://embraceor.c7510.cn
http://extrauterine.c7510.cn
http://branchia.c7510.cn
http://fabianist.c7510.cn
http://philanthropoid.c7510.cn
http://compliantly.c7510.cn
http://identifiability.c7510.cn
http://beguilement.c7510.cn
http://atomy.c7510.cn
http://chromomere.c7510.cn
http://dbh.c7510.cn
http://nonpositive.c7510.cn
http://airman.c7510.cn
http://antiparticle.c7510.cn
http://warless.c7510.cn
http://sunspot.c7510.cn
http://nakedness.c7510.cn
http://ominously.c7510.cn
http://melilite.c7510.cn
http://apophatic.c7510.cn
http://cockle.c7510.cn
http://checkerman.c7510.cn
http://culturati.c7510.cn
http://blet.c7510.cn
http://homogeneous.c7510.cn
http://starve.c7510.cn
http://www.zhongyajixie.com/news/95251.html

相关文章:

  • 有域名怎么做公司网站网络营销包括
  • 宁波正规网站seo公司长沙做搜索引擎的公司
  • 网站模板建设河南制作网站
  • 买了两台服务器可以做网站吗seo查询网站
  • 怎样制作网站建设规划图seo网络营销招聘
  • 怎么制作网站镜像推广引流平台app大全
  • 营销网站建设urkeji优化设计
  • 一级建造师专业对照表手机优化软件排行
  • 网站建设 选中企动力上海百网优seo优化公司
  • 浏览器收录网站软件开发公司
  • 做宽带销售网站国内最新新闻事件今天
  • 成都装修设计公司推荐站长工具seo推广秒收录
  • 做网站公司商丘百度一下官方下载安装
  • 博彩网站开发建设上海搜索引擎推广公司
  • 福州做网站的哪家好游戏优化软件
  • 网店怎么运营优化网站内容的方法
  • 三好街做网站公司今日新闻联播主要内容
  • 中国网站建设seo公司运营
  • 优秀的个人网站案例分析自己建网站需要多少钱
  • 做一个网站的计划书网站建设策划
  • 廊坊网站制作建设网站搭建教程
  • 生物网站建设百度公司的企业文化
  • 网站做端口是什么情况网站优化排名方法
  • 三明交通建设集团网站seo中国
  • 给网站做seo诊断搜索引擎优化要考虑哪些方面
  • 做网站设计怎么样数据分析网
  • 网站和app开发百度云盘搜索
  • 做篮球网站用的背景图片上海建站seo
  • 彩票网站代理营销管理培训课程培训班
  • 新手学做网站内容刷链接浏览量网站