#438
展开↯#439
展开↯#440
作者:广西河池市
mysql的锁和存取钱
在处理锁的问题上,经常听到:共享锁、排它锁、悲观锁、乐观锁、行级锁、表级锁。
共享锁: 就是在读取数据的时候,给数据添加一个共享锁。共享和共享直接是不冲突的,但是和排他锁是冲突的。
排他锁: 更新数据的时候,安装排他锁,禁止其他一切行为。
场 景:老公去在 ATM 上取钱,老婆在柜台存钱,假设这个账户中有 1000 元。老公首先执行查询操作,查询到账户余额为 1000 此时程序 将 1000 拿到内存中,老公取了200 元,程序就执行了更新操作将账户余额改为 800,但是当老公的程序没有 commit 的时候,老婆查询账户,此时账户余额还是 1000 元,老婆存入 200 元,程序执行了更新操作将账户余额改为 1200,然后老公将更新语句提交,接着老婆也将更新语句提交。最后导致的结果就是该账户的余额为 1200,这就是更新丢失的问题。引发更新丢失的根源就是查询上,因为双方都是根据从数据库查询到的数据再对数据库中的数据进行更新的。
解决更新丢失有三个方案:
(1) 将事务隔离级别设置为最高,采用死锁策略。
(2) 采用悲观锁,悲观锁不是数据库中真正的锁,是人们看待事务的态度。
(3) 采用乐观锁,乐观锁也不是数据库中真正的锁。
如 果我们采用的是第一个方案时,老公进行查询操作,数据库为表增加了共享锁,老婆进行查询操作时数据库也增加了一个共享锁。但是当老公进行更新数据库操作 时,由于老婆拿着共享锁,导致老公不能增加排它锁,老婆进行更新操作时,因为老公拿着共享锁,导致老婆也拿不到排它锁,这就发生了死锁现象,你等我,我等你。在 mysql 中,处理死锁的方案是释放掉一方的锁。这样就保证了一方更新成功,但是这种性能极低,因为数据库频繁在解决死锁问题。
悲观锁(更新多,查询少时用)
如果我们采用的是第二个方案时,即采用悲观锁。就是我们在操作数据库时采用悲观的态度,认为别人会在此时并发访问数据库。
我们在查询语句中 select * from account where name='aaa' for update; 等于加了排它锁。
当老公查询余额的时候,select money from account where name='aaa' for update; 增加了排它锁,
老婆查询账户余额的时候, select money from account where name='aaa' for update; 也要求对数据库加排它锁,
因为老公已经拿到了排它锁,导致老婆不能加锁,所以老婆只有等待老公执行完毕,释放掉锁以后才能继续操作。
乐观锁(更新少,查询多时用)
如 果我们采用的是第三个方案时,即采用乐观锁,就是我们在操作数据库的时候会认为没有其它用户并发访问,但是乐观锁也不是完全乐观的,乐观锁是采用版本号的 方式进行控制的。在数据库表中有一列版本号。从数据库中查询的时候,将版本号也查询过来,在进行更新操作的时候,将版本号加1,查询条件的版本号还是查询过来的版本号。
比如:
老公执行查询操作
select money,version from account where name='aaa';
假设此时查询到的版本号为 0,
老公在进行更新操作
update account set money=money+100,version=version+1 where name='aaa' and version=0;
未提交时老婆来查询,查询到的版本号依然是 0,
老婆也执行更新操作
update account set money=money+100,version=version+1 where name='aaa' and version=0;
现在老公提交了事务,老婆再提交事务的时候发现版本号为 0 的记录没有了,所以就避免了数据丢失的问题。不过这种情况也导致了多个用户更新操作时,只有一个用户的更新被执行。
行级别的锁:
select * from employee where employeeID=9857 for update; where 后边是索引列 不是索引列那么就为表级别的锁
在处理锁的问题上,经常听到:共享锁、排它锁、悲观锁、乐观锁、行级锁、表级锁。
共享锁: 就是在读取数据的时候,给数据添加一个共享锁。共享和共享直接是不冲突的,但是和排他锁是冲突的。
排他锁: 更新数据的时候,安装排他锁,禁止其他一切行为。
场 景:老公去在 ATM 上取钱,老婆在柜台存钱,假设这个账户中有 1000 元。老公首先执行查询操作,查询到账户余额为 1000 此时程序 将 1000 拿到内存中,老公取了200 元,程序就执行了更新操作将账户余额改为 800,但是当老公的程序没有 commit 的时候,老婆查询账户,此时账户余额还是 1000 元,老婆存入 200 元,程序执行了更新操作将账户余额改为 1200,然后老公将更新语句提交,接着老婆也将更新语句提交。最后导致的结果就是该账户的余额为 1200,这就是更新丢失的问题。引发更新丢失的根源就是查询上,因为双方都是根据从数据库查询到的数据再对数据库中的数据进行更新的。
解决更新丢失有三个方案:
(1) 将事务隔离级别设置为最高,采用死锁策略。
(2) 采用悲观锁,悲观锁不是数据库中真正的锁,是人们看待事务的态度。
(3) 采用乐观锁,乐观锁也不是数据库中真正的锁。
如 果我们采用的是第一个方案时,老公进行查询操作,数据库为表增加了共享锁,老婆进行查询操作时数据库也增加了一个共享锁。但是当老公进行更新数据库操作 时,由于老婆拿着共享锁,导致老公不能增加排它锁,老婆进行更新操作时,因为老公拿着共享锁,导致老婆也拿不到排它锁,这就发生了死锁现象,你等我,我等你。在 mysql 中,处理死锁的方案是释放掉一方的锁。这样就保证了一方更新成功,但是这种性能极低,因为数据库频繁在解决死锁问题。
悲观锁(更新多,查询少时用)
如果我们采用的是第二个方案时,即采用悲观锁。就是我们在操作数据库时采用悲观的态度,认为别人会在此时并发访问数据库。
我们在查询语句中 select * from account where name='aaa' for update; 等于加了排它锁。
当老公查询余额的时候,select money from account where name='aaa' for update; 增加了排它锁,
老婆查询账户余额的时候, select money from account where name='aaa' for update; 也要求对数据库加排它锁,
因为老公已经拿到了排它锁,导致老婆不能加锁,所以老婆只有等待老公执行完毕,释放掉锁以后才能继续操作。
乐观锁(更新少,查询多时用)
如 果我们采用的是第三个方案时,即采用乐观锁,就是我们在操作数据库的时候会认为没有其它用户并发访问,但是乐观锁也不是完全乐观的,乐观锁是采用版本号的 方式进行控制的。在数据库表中有一列版本号。从数据库中查询的时候,将版本号也查询过来,在进行更新操作的时候,将版本号加1,查询条件的版本号还是查询过来的版本号。
比如:
老公执行查询操作
select money,version from account where name='aaa';
假设此时查询到的版本号为 0,
老公在进行更新操作
update account set money=money+100,version=version+1 where name='aaa' and version=0;
未提交时老婆来查询,查询到的版本号依然是 0,
老婆也执行更新操作
update account set money=money+100,version=version+1 where name='aaa' and version=0;
现在老公提交了事务,老婆再提交事务的时候发现版本号为 0 的记录没有了,所以就避免了数据丢失的问题。不过这种情况也导致了多个用户更新操作时,只有一个用户的更新被执行。
行级别的锁:
select * from employee where employeeID=9857 for update; where 后边是索引列 不是索引列那么就为表级别的锁
文章:PHP高并发Redis MySQL重复插入测试笔记 发表时间:2018-09-03, 15:26:34
#441
作者:广西河池市
PDO 的事务处理
事务处理具有四个特性:原子性、一致性、独立性、持久性。
并不是所有的数据库都支持事务处理的,PDO 为能够执行事务处理的数据库提供事务支持。
配置事务处理需注意:
1、关闭 PDO 的自动提交;
2、开启一个事务需要的方法;
3、一般事务处理是运行在 try...catch...语句中,当事务失败时执行 catch 代码段。
在事务中的 SQL 语句,如果出现错误,那么所有的 SQL 都不执行。当所有 SQL 有无误的时候,才提交执行。
事务处理具有四个特性:原子性、一致性、独立性、持久性。
并不是所有的数据库都支持事务处理的,PDO 为能够执行事务处理的数据库提供事务支持。
配置事务处理需注意:
1、关闭 PDO 的自动提交;
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, false);
Run code
Cut to clipboard
2、开启一个事务需要的方法;
$pdo->beginTransaction(); // 开启一个事务
$pdo->commit(); // 提交事务
$pdo->rollback(); // 回滚事务
Run code
Cut to clipboard
3、一般事务处理是运行在 try...catch...语句中,当事务失败时执行 catch 代码段。
<?php
try {
$pdo->beginTransaction(); // 开启一个事务
$row = null;
$row = $pdo->exec("xxx"); // 执行第一个 SQL
if (!$row)
throw new PDOException('提示信息或执行动作'); // 如出现异常提示信息或执行动作
$row = $pdo->exec("xxx"); // 执行第二个 SQL
if (!$row)
throw new PDOException('提示信息或执行动作');
$pdo->commit();
} catch (PDOException $e) {
$pdo->rollback(); // 执行失败,事务回滚
exit($e->getMessage());
}
?>
Run code
Cut to clipboard
在事务中的 SQL 语句,如果出现错误,那么所有的 SQL 都不执行。当所有 SQL 有无误的时候,才提交执行。
文章:PHP高并发Redis MySQL重复插入测试笔记 发表时间:2018-09-03, 14:44:47
#442
作者:广西河池市
结论:
1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。 #,广西河池市,2018-09-01,16:30:43, 任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
编译器把finally中的return实现为一个warning。 #,广西河池市,2018-09-01,16:31:39, 在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。
在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,
因此,即使finally中对变量x进行了改变,但是不会影响返回结果。
它应该使用栈保存返回值。 #,广西河池市,2018-09-01,16:33:09, 如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况,: 1)如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。 2)如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。 #,广西河池市,2018-09-01,16:33:53, 因为使用栈保存返回值,即使finally中执行i++,但是影响不到之前保存下来的具体的值。 所以return影响不了基本型的值。 而修改list ,map,自定义类等引用类型时,虽然进入finally之前保存了引用的地址,所以在finally中引用地址指向的内容改变了, 影响了返回值。 #,广西河池市,2018-09-01,17:31:48, :try{ return;}catch(){return;} finally{return;} 程序执行try块中return之前(包括return语句中的表达式运算)代码; 有异常:执行catch块中return之前(包括return语句中的表达式运算)代码; 则再执行finally块,因为finally块中有return所以提前退出。 无异常:则再执行finally块,因为finally块中有return所以提前退出。 finally中有return会吃掉异常的 #,广西河池市,2018-09-01,17:32:23, 1.影响返回结果的前提是在 非 finally 语句块中有 return 且非基本类型 2.不影响返回结果 的前提是 非 finally 块中有return 且为基本类型 这也解释了,为什么Date类型是被修改的,究其本质 基本类型在栈中存储,返回的是真实的值,而引用类型返回的是其浅拷贝堆地址.所以才会改变~ #,广西河池市,2018-09-01,17:32:49, 基本数据类型是不能修改的,其他的可以修改,包括date #,广西河池市,2018-09-01,17:33:44, date类型底层貌似是对long类型的数据的封装,也就是说JVM可能在编译的时候指定了一个常量值保存了起来,所以在finally块中修改的其实不是date底层所指向的那个副本,而是对类似于基本数据类型的修改,所以返回的结果仍然是一开始编译好的时候指定的副本。也就是没变的原因。 而其他的对象(引用类型)则是被finally块中的代码改变了所引用变量的真实数据,所以发生了改变。 也就是说,严格来讲,Date类型是个伪对象类型。 以上均为个人观点,如果有误,还望指出,大家一起研究。 :)
1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
编译器把finally中的return实现为一个warning。
在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,
因此,即使finally中对变量x进行了改变,但是不会影响返回结果。
它应该使用栈保存返回值。
文章:finally代码块 发表时间:2018-09-01, 16:30:09
#443
作者:广西河池市
即使try里包含continue,break,return,try块结束后,finally块也会执行。
文章:finally代码块 发表时间:2018-09-01, 16:28:53
#444
作者:广西河池市
我觉得当try,finally都有return时,不能叫做覆盖,因为try中的return只执行了表达式,然后放在某个空间,但是并没有执行return(因为一旦执行return程序就结束了),然后执行finally里面的代码,接着finally中遇到return直接结束了程序,所以应该说是执行了try中return的表达式,而被finally中的return提前结束比较好,并不是finally中的return覆盖了try中的return。 #,广西河池市,2018-09-01,16:26:57, 对于基本类型而言 是值传递 所以2被缓存的是值 而不是变量的地址 再return出去就是2 #,广西河池市,2018-09-01,16:27:14, String类型不可变 也就是String a = "abc";后,存储"abc"字符串的地址的内容不可变,而a变量的重新赋值是通过指向另一块内存地址来实现的。同int型变量。String型变量暂存的是"abc"的存储地址,因此不会发生变化。你可以用StringBuffer、StringBuilder等可变字符类型来对比。
文章:finally代码块 发表时间:2018-09-01, 16:26:11
#445
作者:广西河池市
Mysql查询某字段值重复的数据
查询user表中,user_name字段值重复的数据及重复次数
查询user表中,user_name字段值重复的数据及重复次数
select user_name,count(*) as count from user group by user_name having count>1;Run code
Cut to clipboard
文章:PHP高并发Redis MySQL重复插入测试笔记 发表时间:2018-08-31, 20:11:30
#447
作者:广西河池市
第一:如果线程1插入订单的过程中,线程2再去插入此时线程2会返回“订单已存在”的提示 ,然后问题是如果线程1插入失败,那么最终结果是数据库里并没有这个订单,但是线程2的用户却看到了“订单已存在” 这样的“错误”提示
第二:关于数据库事务的问题,在ssh这种框架里,经常出现配置的事务是在service方法执行前开启事务,在方法执行完以后提交事务,如果是这种情况的话,那还是会出现数据重复的问题,比如线程1 执行完 MemcacheUtil.del(key); 方法时 此时线程1的事务还没有提交(也就是说数据库里还没有相应的数据),但是缓存里的key已经被删掉了,与此同时线程2看不到数据库里的数据,缓存里的数据也没有 #,广西河池市,2018-08-31,14:53:49, 多台服务器部署,MemcacheUtil 要保证是全局的,不然也有问题
第二:关于数据库事务的问题,在ssh这种框架里,经常出现配置的事务是在service方法执行前开启事务,在方法执行完以后提交事务,如果是这种情况的话,那还是会出现数据重复的问题,比如线程1 执行完 MemcacheUtil.del(key); 方法时 此时线程1的事务还没有提交(也就是说数据库里还没有相应的数据),但是缓存里的key已经被删掉了,与此同时线程2看不到数据库里的数据,缓存里的数据也没有
文章:处理高并发情况下的DB插入 发表时间:2018-08-31, 14:53:36
#448
作者:广西河池市宜州市
PHP中利用redis实现消息队列处理高并发请求
#,广西河池市宜州市,2018-08-30,18:09:43, #,广西河池市宜州市,2018-08-30,18:17:30,
先将商品库存存入队列:
客户执行下单操作:
将请求存入redis
为了模拟多个用户的请求,使用一个for循环替代
//redis数据入队操作
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
for($i=0;$i<50;$i++){
try{
$redis->LPUSH('click',rand(1000,5000));
}catch(Exception $e){
echo $e->getMessage();
}
}
在后台进行数据处理
守护进程
//redis数据出队操作,从redis中将请求取出
$redis = new Redis();
$redis->pconnect('127.0.0.1',6379);
while(true){
try{
$value = $redis->LPOP('click');
if(!$value){
break;
}
//var_dump($value)."\n";
/*
* 利用$value进行逻辑和数据处理
*/
}catch(Exception $e){
echo $e->getMessage();
}
}
Run code
Cut to clipboard
//关于redis事务的案例
header("content-type:text/html;charset=utf-8");
$redis = new redis();
$redis->connect('localhost', 6379);
//$result = $redis->connect('localhost', 6379);
//$redis = Yii::app()->redis;
$redis->set("testName","33");
//$mywatchkey = $redis->get("mywatchkey");
$mywatchkey = $redis->get('testName');
//($test);exit;
$rob_total = 100; //抢购数量
if($mywatchkey<$rob_total){
$redis->watch("testName");
$redis->multi();
//设置延迟,方便测试效果。
sleep(5);
//插入抢购数据
$redis->hSet("testName","user_id_".mt_rand(1, 9999),time());
$redis->set("testName",$mywatchkey+1);
$rob_result = $redis->exec();
if($rob_result){
$mywatchlist = $redis->hGetAll("testName");
echo "抢购成功!<br/>";
echo "剩余数量:".($rob_total-$mywatchkey-1)."<br/>";
echo "用户列表:<pre>";
var_dump($mywatchlist);
}else{
echo "手气不好,再抢购!";exit;
}
}Run code
Cut to clipboard
先将商品库存存入队列:
<?php
$store=1000; //商品库存
$redis=new Redis();
$result=$redis->connect('127.0.0.1',6379);
$res=$redis->llen('goods_store');
for($i=0; $i<$store; $i++){
$redis->lpush('goods_store',1);
}
echo $redis->llen('goods_store');
?> Run code
Cut to clipboard
客户执行下单操作:
$redis=new Redis();
$result=$redis->connect('127.0.0.1',6379);
$count = $redis->lpop('goods_store');
if(!$count){
echo '抢购失败!';
return;
} Run code
Cut to clipboard
文章:php redis 学习笔记 发表时间:2018-08-30, 18:08:32
#450
展开↯#451
作者:广西南宁市
老板发工资给我,不是因为我为公司做事,而是因为我为了这份工作,没能为自己做事。
不是因为公司得到了什么,而是因为我失去了什么。
所以公司给我的那份工资,严格来说不是工资,是赔偿。
其中分别就是,你出粮给我,我要多谢你。
你赔偿给我,你要加多一句“对不起”。
——黄子华
雇佣关系而已,我时刻提醒自己
第1次你给我发错(多)了,我原谅你。
第2次你又发错(少)了,怎么能继续原谅你?
一个很老的笑话
15830371000
文章:@意见反馈/技术支持/伊网/安企网 发表时间:2017-09-14, 11:48:07
#452
展开↯#453
作者:广西河池市宜州市
安装nginx #,广西河池市宜州市,2018-08-01,10:10:20, 输入命令./nginx -t
看到如下显示nginx.conf syntax is ok
nginx.conf test is successful
说明配置文件正确 #,广西河池市宜州市,2018-08-01,10:11:12,
在启动命令-c前加-t #,广西河池市宜州市,2018-08-10,23:22:32, #,广西河池市宜州市,2018-08-21,15:18:10,
Linux下ftp服务可以通过搭建vsftpd服务来实现
执行 systemctl start vsftpd.service 启动vsftp服务,然后可以通过命令: systemctl status vsftpd.service 查看ftp服务的运行状态
#,广西河池市宜州市,2018-08-21,15:53:09, sftp和ftp区别在于:文件的安全性
FTP是一种文件传输协议,一般是为了方便数据共享的。包括一个FTP服务器和多个FTP客户端。FTP客户端通过FTP协议在服务器上下载资源。
SFTP协议是在FTP的基础上对数据进行加密,使得传输的数据相对来说更安全。但是这种安全是以牺牲效率为代价的。
SFTP的传输效率比FTP要低。
//进入nginx目录
cd nginxRun code
Cut to clipboard
看到如下显示nginx.conf syntax is ok
nginx.conf test is successful
说明配置文件正确
wget -O wordpress.zip http://www.linuxde.net/download.aspx?id=1080
Centos出现-bash: unzip: command not found的解决办法
利用unzip命令解压缩的时候,出现-bash:
unzip: command not found的错误。
unzip——命令没有找到,其原因肯定是没有安装unzip。
利用一句命令就可以解决了。
命令是:
yum install -y unzip zip
安装成功后就可以使用unzip命令Run code
Cut to clipboard
Linux下ftp服务可以通过搭建vsftpd服务来实现
执行 systemctl start vsftpd.service 启动vsftp服务,然后可以通过命令: systemctl status vsftpd.service 查看ftp服务的运行状态
systemctl stop vsftpd.serviceRun code
Cut to clipboard
FTP是一种文件传输协议,一般是为了方便数据共享的。包括一个FTP服务器和多个FTP客户端。FTP客户端通过FTP协议在服务器上下载资源。
SFTP协议是在FTP的基础上对数据进行加密,使得传输的数据相对来说更安全。但是这种安全是以牺牲效率为代价的。
SFTP的传输效率比FTP要低。
文章:LINUX安装NGINX笔记 发表时间:2018-06-14, 17:49:17
#454
作者:广西南宁市
文章:程序员编程常用网页工具集[游戏] 发表时间:2017-07-29, 10:26:00
#455
作者:广西河池市宜州市
文章:@意见反馈/技术支持/伊网/安企网 发表时间:2018-08-02, 15:09:59
#456
作者:广西河池市宜州市
到底是“学术研究无禁区”,还是“思想道德无底线” #,广西河池市宜州市,2018-08-17,09:14:03, 集权可以跑的很快,但刹不住车
文章:@意见反馈/技术支持/伊网/安企网 发表时间:2018-08-17, 09:10:02
李振球
622848 083830840 9179