<?php header( 'content-type:text/html;charset=utf-8' );
// //无控制
// $DB_DSN = 'mysql:dbname=blog;host=127.0.0.1';
// $DB_USER = 'root';
// $DB_PWD = 'root';
// $pdo = new PDO($DB_DSN, $DB_USER, $DB_PWD);
// $pdo->setAttribute(PDO::ATTR_PERSISTENT, true); // 设置数据库连接为持久连接
// $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 设置抛出错误
// $pdo->setAttribute(PDO::ATTR_ORACLE_NULLS, true); // 设置当字符串为空转换为 SQL 的 NULL
// $pdo->query('SET NAMES utf8'); // 设置数据库编码
// function build_order_no() { //生成唯一订单
// return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
// }
// $price=10;
// $user_id=1;
// $goods_id=1;
// $sku_id=11;
// $number=1;
// //模拟下单操作
// //库存是否大于0
// //解锁 此时ih_store数据中goods_id='$goods_id' and sku_id='$sku_id' 的数据被锁住(注3),其它事务必须等待此次事务 提交后才能执行
// $sql = "select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id'";
// $rs = $pdo->query($sql);
// $row = $rs->FetchColumn();
// if($row > 0){ //高并发下会导致超卖
// $order_sn = build_order_no();
// //生成订单
// $sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)
// values('$order_sn','$user_id','$goods_id','$sku_id','$price')";
// $order_rs = $pdo->query($sql);
// // var_dump($order_rs);die;
// //库存减少
// $sql="update ih_store set number=number-{$number} where sku_id='$sku_id'";
// $store_rs = $pdo->query($sql);
// // if($store_rs->rowCount()) {
// // error_log('订单号:'.$order_sn.'库存减少成功<br>');
// // } else {
// // error_log('订单号:'.$order_sn.'库存减少失败<br>');
// // }
// // }else{
// // //error_log('库存不够<br>');
// }
// //开启事物
// $DB_DSN = 'mysql:dbname=blog;host=127.0.0.1';
// $DB_USER = 'root';
// $DB_PWD = 'root';
// $pdo = new PDO($DB_DSN, $DB_USER, $DB_PWD);
// $pdo->setAttribute(PDO::ATTR_PERSISTENT, true); // 设置数据库连接为持久连接
// $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 设置抛出错误
// $pdo->setAttribute(PDO::ATTR_ORACLE_NULLS, true); // 设置当字符串为空转换为 SQL 的 NULL
// $pdo->query('SET NAMES utf8'); // 设置数据库编码
// function build_order_no() { //生成唯一订单
// return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
// }
// $price=10;
// $user_id=1;
// $goods_id=1;
// $sku_id=11;
// $number=1;
// //模拟下单操作
// //库存是否大于0
// //解锁 此时ih_store数据中goods_id='$goods_id' and sku_id='$sku_id' 的数据被锁住(注3),其它事务必须等待此次事务 提交后才能执行
// $pdo->query('BEGIN');
// $sql = "select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id'";
// $rs = $pdo->query($sql);
// $row = $rs->FetchColumn();
// if($row > 0){ //高并发下会导致超卖
// $order_sn = build_order_no();
// //生成订单
// $sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)
// values('$order_sn','$user_id','$goods_id','$sku_id','$price')";
// $order_rs = $pdo->query($sql);
// //库存减少
// $sql="update ih_store set number=number-{$number} where sku_id='$sku_id'";
// $store_rs = $pdo->query($sql);
// // if($store_rs->rowCount()) {
// // error_log('订单号:'.$order_sn.'库存减少成功<br>');
// $pdo->query('COMMIT');
// // } else {
// // error_log('订单号:'.$order_sn.'库存减少失败<br>');
// // }
// // var_dump($order_rs);die;
// }else{
// //error_log('库存不够<br>');
// $pdo->query('ROLLBACK');
// }
// //使用非阻塞的文件排他锁
// $DB_DSN = 'mysql:dbname=blog;host=127.0.0.1';
// $DB_USER = 'root';
// $DB_PWD = 'root';
// $pdo = new PDO($DB_DSN, $DB_USER, $DB_PWD);
// $pdo->setAttribute(PDO::ATTR_PERSISTENT, true); // 设置数据库连接为持久连接
// $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 设置抛出错误
// $pdo->setAttribute(PDO::ATTR_ORACLE_NULLS, true); // 设置当字符串为空转换为 SQL 的 NULL
// $pdo->query('SET NAMES utf8'); // 设置数据库编码
// function build_order_no() { //生成唯一订单
// return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
// }
// $price=10;
// $user_id=1;
// $goods_id=1;
// $sku_id=11;
// $number=1;
// //模拟下单操作
// //库存是否大于0
// $fp = fopen("lock.txt", "w+");
// if(!flock($fp,LOCK_EX | LOCK_NB)){
// echo "系统繁忙,请稍后再试";
// return;
// }
// $sql = "select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id'";
// $rs = $pdo->query($sql);
// $row = $rs->FetchColumn();
// if($row > 0){ //高并发下会导致超卖
// $order_sn = build_order_no();
// //库存减少
// $sql="update ih_store set number=number-{$number} where sku_id='$sku_id'";
// $store_rs = $pdo->query($sql);
// if($store_rs->rowCount()) {
// //生成订单
// $sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)
// values('$order_sn','$user_id','$goods_id','$sku_id','$price')";
// $order_rs = $pdo->query($sql);
// error_log('订单号:'.$order_sn.'库存减少成功<br>');
// } else {
// error_log('订单号:'.$order_sn.'库存减少失败<br>');
// }
// flock($fp,LOCK_UN);//释放锁
// }else{
// error_log('库存不够<br>');
// }
// fclose($fp);
//队列
$store = 500;
$redis = new Redis();
$result = $redis ->connect( '127.0.0.1' , 6379);
$redis ->FLUSHALL();
$res = $redis ->llen( 'goods_store' );
$count = $store - $res ;
for ( $i =1; $i <= $count ; $i ++){
$redis ->lpush( 'goods_store' , $i );
}
echo $redis ->llen( 'goods_store' );
exit ;
$DB_DSN = 'mysql:dbname=blog;host=127.0.0.1' ;
$DB_USER = 'root' ;
$DB_PWD = 'root' ;
$pdo = new PDO( $DB_DSN , $DB_USER , $DB_PWD );
$pdo ->setAttribute(PDO::ATTR_PERSISTENT, true); // 设置数据库连接为持久连接
$pdo ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 设置抛出错误
$pdo ->setAttribute(PDO::ATTR_ORACLE_NULLS, true); // 设置当字符串为空转换为 SQL 的 NULL
$pdo ->query( 'SET NAMES utf8' ); // 设置数据库编码
function build_order_no() { //生成唯一订单
$sn = microtime(). '' .rand(10000,100000). '' .microtime(). '' .rand(10000,100000);
return $sn ;
//return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}
$price =10;
$user_id =1;
$goods_id =1;
$sku_id =11;
$number =1;
//模拟下单操作
$redis = new Redis();
$result = $redis ->connect( '127.0.0.1' , 6379);
$count = $redis ->rpop( 'goods_store' );
if (! $count ){
error_log ( '队列' . $count . 'redis:库存不足' );
} else {
$order_sn = build_order_no();
//生成订单
$sql = "insert into ih_order(order_sn,user_id,goods_id,sku_id,price) values('$order_sn','$user_id','$goods_id','$sku_id','$price')" ;
$order_rs = $pdo ->query( $sql );
//库存减少
$sql = "update ih_store set number=number-{$number} where sku_id='$sku_id'" ;
$store_rs = $pdo ->query( $sql );
if ( $store_rs ->rowCount()) {
error_log ( '队列:' . $count . '订单号:' . $order_sn . '库存减少成功<br>' );
} else {
error_log ( '队列:' . $count . '订单号:' . $order_sn . '库存减少失败<br>' );
}
}
|
自我感觉,文件排它锁比较慢,pdo处理高并发效果一般,redis是最有效的