涉及 mysql 标签的文章 所有标签


继续关于并发操作数据库问题的研究
8年前
  • 206
  • 201

继续关于并发操作数据库问题的研究

就很久之前自己写过的一篇关于mysql锁表的文章,http://paperen.com/post/lock-table,在目前来看实现上并不存在太大的问题,而当情况放在高并发的情形下那么该解决方案会变得不那么可行,原因是对数据库update操作实在频繁而且高并发情况下大量操作需要等待某个解锁后才能执行

就接着之前那篇文章说的情况

商店现在某商品只有1件库存,然后A与B在网上进行下订,A与B几乎同时(或许也就差几毫秒,A比B快那么一点点)进行

在这种应用情景下,我们先建立一个数据表 product,注意到使用了innoDB引擎

CREATE TABLE `product` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `num` mediumint(8) DEFAULT '0',
  `goods` varchar(60) CHARACTER SET latin1 DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `product` VALUES ('1', '1', 'test');

下面为基本php代码

<?php

$dbhost = '127.0.0.1';
$dbname = 'test';
$dbpwd = '';
$dbuser = 'root';

try {

 $conn = mysqli_connect($dbhost, $dbuser, $dbpwd);
 if ( !$conn ) throw new Exception('db error');
 mysqli_select_db($conn, $dbname);
 mysqli_query($conn,'set names UTF8');

 $id = 1;
 
 $sql = "select * from product where id='{$id}'";
 $query = mysqli_query($conn, $sql);
 $data = mysqli_fetch_array($query, MYSQLI_ASSOC);
 
 if ( $data['num'] <= 0 ) throw new Exception('product sold out');
 
 sleep(1);
 $sql = "update product set num=num-1 where id='{$id}'";
 mysqli_query($conn, $sql);
 echo 'ok';
 
} catch( Exception $e ) {
 echo $e->getMessage();
}

阅读更多
关于Mysql的两个实用技术
14年前
  • 0
  • 0

关于Mysql的两个实用技术

paperen对mysql的接触是从玩php开始的,paperen并没有学过SQL,但是自学了一些,对于mysql其实也不是专研得太深,而最近又重新看一遍《PHP和MySql Web开发 第4版》才有发现mysql中有些东西paperen到现在还没有玩过~~所以现在paperen再亲自测试一下并拿出来跟大家分享一下,其实大家有这本书的话不妨自己翻开,再看看12,13章的内容,当然如果你是已经了解并玩得很熟了那么可以忽略了。

大概总结了下,这两章介绍了一些玩法有:mysql prepared,pear mdb2,权限分配,sql优化分析,备份与恢复数据库,主从同步数据库,innodb事务与外键,存储过程。都是一些很实用的技巧,而这里paperen只具体说说主从同步数据库与存储过程,其他技巧自己去查查资料吧。

主从同步数据库,这个概念应该很好理解,其实就是集群数据库的概念,在客户端看上去数据库只有一个,但是实质上不止一个,可能是多个数据库在维持,实质上说这个技巧是为了保证web平台的稳定而使用的,paperen觉得这个技巧并不是用来防止数据出错(数据出错站在mysql的层面来看是根本没法避免的,只能靠备份来预防)是为了提高可靠性。

阅读更多
后知后觉的Mysql锁表应用
13年前
  • 2
  • 1

后知后觉的Mysql锁表应用

在看CI(codeigniter)database那一节的手册发现其自带了事务的处理,之后又不知不觉地查了一些资料,在某个地方看到有个例子,具体描述类似如下:商店现在某商品只有1件库存,然后A与B在网上进行下订,A与B几乎同时(或许也就差几毫秒,A比B快那么一点点)进行。

很明显是只有A才能成功下单的,B则会收到库存不足的提示,但是作为放置在服务端的那个页面(或者称为脚本程序)我们得怎样去处理这个问题呢?或者我先放出一段代码吧。

$sql = "select number from goods where id=1";
$number = intval( $db->result( $db->query( $sql ), 0 ) );
if ( $number > 0 ) {
sleep( 2 );
$sql = "update goods set number=number-1 where id = 1";
if ( $db->query( $sql ) ) {
echo 'Ok!Here you are!';
} else {
echo 'Sorry!Something go wrong!Try it again.';
}
} else {
echo 'No more!you are so late!';
}

这部分代码除了缺少一定注释外都写得没错,当然$db是一个操作数据库的类,我只是将大部分方法封装了,这里的逻辑也是很明显了。

阅读更多