我想知道为什么MySQL不允许在存储过程中锁定表。
我的存储过程中有以下SQL语句:
-- Total amount of money for comments
start transaction;
select @num_comments := count(*)
from `comment` c
where
c.user_id = user_id and
c.payment_rejection = 'NO' and
c.is_recorded = 0;
update `user` u set account_balance += u.comment_price * @num_comments where u.user_id = user_id;
update `comment` c set is_recorded = 1 where c.user_id = user_id and c.payment_rejection = 'NO' and c.is_recorded = 0;
commit;
所以我必须锁定表comment
以防止对它进行任何写入,因为它可能导致第一个SQL语句中选择的行数与实际更新的数量不同。
答案 0 :(得分:1)
先生,在您的代码中,您可以使用ROW_COUNT()
函数代替SELECT count(*)
根据文件:http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_row-count
ROW_COUNT()返回最后一个语句更改,删除或插入的行数(如果它是UPDATE,DELETE或INSERT)。对于其他陈述,该值可能没有意义。
start transaction;
update `comment` c
set is_recorded = 1
where c.user_id = v_user_id
and c.payment_rejection = 'NO'
and c.is_recorded = 0;
SET @num_comments = row_count();
update `user` u
set account_balance += u.comment_price * @num_comments
where u.user_id = v_user_id;
commit;
这样就不需要锁定表,行数不能在语句之间改变,而奖励是整个事务的更高速度。
一些评论:
user_id
列在查询中不明确:
where u.user_id = user_id;
并且update命令更新整个表而不是仅属于一个用户的行 不要在过程中使用与表中列名相同的变量名称,最简单的方法是在变量名前加一些前缀以避免歧义,例如:
where u.user_id = var_user_id;