简体   繁体   English

MySQL InnoDB表锁定在存储过程中

[英]MySQL InnoDB table locking inside stored procedure

I wonder why MySQL does not allow table locking inside a stored procedure. 我想知道为什么MySQL不允许在存储过程中进行表锁定。

I have the following SQL statements inside my stored procedure: 我的存储过程中有以下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;

So I have to lock table comment to prevent any writing to it for it may cause the number of rows selected in the first SQL statement be different from the number of actually updated. 因此,我必须锁定表comment以防止对其进行任何写入,因为它可能导致在第一个SQL语句中选择的行数与实际更新的数量不同。

Sir, in your code you can use ROW_COUNT() function instead of SELECT count(*) 先生,在您的代码中,您可以使用ROW_COUNT()函数而不是SELECT count(*)

According to documentation: http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_row-count 根据文档: http//dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_row-count

ROW_COUNT() returns the number of rows changed, deleted, or inserted by the last statement if it was an UPDATE, DELETE, or INSERT. ROW_COUNT()返回最后一个语句更改,删除或插入的行数(如果它是UPDATE,DELETE或INSERT)。 For other statements, the value may not be meaningful. 对于其他陈述,该值可能没有意义。

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;

In this way there is no need to lock tables, the number of rows cannot change between statements, and a bonus is a higher speed of the whole transaction. 这样就不需要锁定表,行数不能在语句之间改变,而奖励是整个事务的更高速度。

Some comments: 一些评论:
The user_id column is ambiguous in the query: user_id列在查询中不明确:

where u.user_id = user_id;

and the update command updates the whole table instead of rows belong to one user only. 并且update命令更新整个表而不是仅属于一个用户的行。
Don't use the same names for variables in the procedure as columns names in the table, the easiest way is to prepend some prefix to variable names to avoid ambiguity, for example: 不要在过程中使用与表中列名相同的变量名称,最简单的方法是在变量名前加一些前缀以避免歧义,例如:

where u.user_id = var_user_id;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM