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