首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mysql Innodb不返回select with desc order的最后一行

Mysql Innodb不返回select with desc order的最后一行
EN

Stack Overflow用户
提问于 2013-05-03 21:37:24
回答 4查看 756关注 0票数 3

我们有一个类似如下的表方案:

代码语言:javascript
复制
CREATE TABLE IF NOT EXISTS `offers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `campaign_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `price` double NOT NULL,
  `ip` varchar(15) NOT NULL,
  `cdate` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `campaign_id` (`campaign_id`,`price`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin5 AUTO_INCREMENT=190514 ;

对于用户的每个新报价,我们使用以下命令检查最后一个订单是否由同一用户提供:

代码语言:javascript
复制
"select user_id from offers where campaign_id='".$campaign['id']."' order by id desc limit 1"

如果user_id是相同的,我们将阻止新的提议,以保护用户不被意外双击。

如果报价没有任何问题,我们可以通过以下方式插入报价:

代码语言:javascript
复制
"insert into offers(campaign_id,user_id,price,ip,cdate) values (".$campaign['id'].",".$user['id'].",'".$price."','".$_SERVER['REMOTE_ADDR']."',".time().")"

但问题是,select仅在大约1秒后返回最后插入的行。这意味着如果用户点击按钮太快,他们可能会插入多个优惠。

我们使用5.5.30-30.2-log Percona server作为我们的数据库服务器。以下是我们的my.cnf文件:

代码语言:javascript
复制
[mysqld]
datadir                         = /var/lib/mysql
tmpdir                          = /var/lib/mysqltmp
socket                          = /var/lib/mysql/mysql.sock
skip-external-locking           = 1
skip-name-resolve
open-files-limit                = 40000
max_heap_table_size             = 64M
tmp_table_size                  = 64M
log-error                       = /var/log/mysqld.log
thread-cache-size               = 50
table-cache                     = 4096
table-open-cache                = 4096
table-definition-cache          = 512
query-cache-size                = 0
query-cache-limit               = 16M
query-cache-type                = 0
sort-buffer-size                = 1M
read-buffer-size                = 1M
read-rnd-buffer-size            = 8M
join-buffer-size                = 1M
tmp-table-size                  = 64M
max-heap-table-size             = 64M
back-log                        = 100
max-connections                 = 10000
max-connect-errors              = 10000
max-allowed-packet              = 256M
interactive-timeout             = 360
wait-timeout                    = 360
innodb                          = FORCE
key-buffer-size                 = 32M
myisam-sort-buffer-size         = 4M
innodb-buffer-pool-size         = 60G
innodb-log-file-size            = 256M
innodb_log_files_in_group       = 2
innodb-log-buffer-size          = 4M
innodb-file-per-table          = 1
innodb-thread-concurrency       = 8
innodb-flush-log-at-trx-commit  =2
server-id                       = 1
slow-query-log                  = 1
slow-query-log-file             = /var/lib/mysqllogs/slow-log
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-05-04 03:48:51

我认为问题是由多个连接在insert之前选择相同的行引起的,如下所示:

php连接1:选择最后的优惠user_id

php连接2:选择最后的优惠user_id (给出相同的)

php连接1:插入报价

php连接2:插入报价

我解决了这个问题,在select之前锁定表,在insert之后解锁,如下所示:

锁表提供写操作

选择最后一个优惠的user_id

如果它与当前用户插入提议不同

解锁表优惠

票数 0
EN

Stack Overflow用户

发布于 2013-05-03 22:14:16

您是否尝试在Update / Insert事件上使用SQL触发器来检查例如

代码语言:javascript
复制
SELECT count(*) FROM `offers` 
WHERE campaign_id = [Your_value] AND user_id = [Your_value];

等于0,并根据它执行操作。(如果已经存在,请不要做任何修改...)

编辑:顺便说一句,这看起来更像是Ajax / Php /无论您使用什么的问题,而不是MySQL数据库的不正确使用。您应该防止用户在短时间间隔内发送大量请求。

票数 1
EN

Stack Overflow用户

发布于 2013-05-03 21:41:20

MySQL查询缓存。

MySQL将在第一次单击时检查并返回一个空结果,然后它将插入记录,然后每次单击MySQL都将返回空结果的缓存值并允许再次插入。

我们在一个网站上也有类似的事情发生,我正在处理的请求非常接近。

我们最终不得不先运行这个

代码语言:javascript
复制
SET SESSION query_cache_type=0;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16360259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档