MySQL社区

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
查看: 5124|回复: 6
打印 上一主题 下一主题

请大家帮忙解决一个奇怪的锁争用问题

[复制链接]
跳转到指定楼层
1#
发表于 2010-9-23 00:11:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
大家好。
问题大致是这样的:
MySQL版本是5.0,操作系统是debian。
有两个Table,一个是users(用户表),另一个是userdata(用户数据)。
users表的主键是UID,类型为int。
userdata表的主键是DataID,是个自增列,同时有个列UID,是users表中UID列的外键,另外,对列UID和另一个列Category建立了索引。
两个表都为InnoDB,结构大致为:
create table users(
      UID int primary key,
      ### other columns.....
) engine = innodb;
create table userdata(
      DataID int auto_increment primary key,
      UID int,
      Category int,
      ### other columns.....
      Key `Index_UID`(`UID`),
      key `Index_Category`(`Category`),
      constraint `FK_userdata_UID_users_UID` foreign key (`UID`) references `users` (`UID`) on delete cascade
) engine = innodb;
### other tables.....

我的需求是:
我的系统是一个高并发的、大数据量的系统.
我需要在userdata中找出指定的用户当前拥有哪些数据,再根据其当前拥有的数据判断应该给该用户增加、删除、更新哪些数据。
为了保证用来判断的数据的正确性,需要在每次查询数据前对数据进行加锁,待更新完数据后才释放锁。
整个操作在一个transaction中进行。
步骤如下:
(1):创建transaction : Trans
      select * from users where UID = xxx for update;
      返回Trans
(2):使用(1)中返回的Trans
      select * from userdata where UID = xxx and category in (c1, c2, c3);
(3):根据(2)中返回的数据判断需要增加、删除、更新一些数据,同样使用Trans
      update userdata ....
      update userdata ....
      insert userdata ....
      insert userdata ....
      delete userdata where DataID in (x1, x2, x3...);
      ### update other tables ....
      ### insert other tables ....
      ### delete other tables ....
(4):以上步骤若成功执行,则 commit Trans,否则rollback Trans。

以上代码在少用户量的环境下测试的时候没什么问题,但在大用户量的情况下却出现大量的锁等待,并有死锁的情况发生。
很多锁等待发生在select * from users where UID = xxx for update 语句处。

请各位帮忙分析一下以上逻辑存在什么问题,为何会有这么多的锁等待并发生死锁呢?
又或者各位有什么更好的实现逻辑?

谢谢。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享淘帖 顶 踩
2#
发表于 2010-9-25 11:07:07 | 只看该作者
你更新的是userdata表,不用给user表加锁的呀...
还有能不放在Trans中的尽量提取出来。
3#
 楼主| 发表于 2010-9-25 11:15:19 | 只看该作者
因为还需要更新其它的Table,并且很有可能不在一个DB中,
所以对users表加锁。
如果对userdata表加锁的话,很容易引发死锁。
4#
 楼主| 发表于 2010-9-25 11:19:05 | 只看该作者
另外,Transaction是必须的,
有大量的逻辑需要处理,并且必要时需要回滚。
5#
发表于 2010-9-25 16:45:29 | 只看该作者
你没有体会我的意思
如果你不交互,只是一次性提取user表信息,应该是不用加锁
要不就把外键去了试试(这里只是怀疑)...
6#
 楼主| 发表于 2010-9-25 17:08:48 | 只看该作者
对Users表加锁的用意是为了每次对UserData表(及其它表)中的数据检索时都得到正确的结果,
需要根据UserData表中的数据(及用户在其它表中的数据)来判断应该接下来执行哪些操作。
经测试验证,外键并不会影响锁。
7#
发表于 2010-9-26 09:37:24 | 只看该作者
那么对user加锁,然后执行后续N步操作,而后续N步操作需要较长时间,然后你又是大并发,既然你这么肯定逻辑没有问题和要改进的地方,又不能切碎,等待你的只能是糟糕的情况了...
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|申请友链|小黑屋|Archiver|手机版|MySQL社区 ( 京ICP备07012489号   
联系人:周生; 联系电话:13911732319

GMT+8, 2024-5-18 09:04 , Processed in 0.079978 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表