|  | 
 
| 大家好。 问题大致是这样的:
 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 语句处。
 
 请各位帮忙分析一下以上逻辑存在什么问题,为何会有这么多的锁等待并发生死锁呢?
 又或者各位有什么更好的实现逻辑?
 
 谢谢。
 
 | 
 |