【发布时间】:2013-09-17 20:15:41
【问题描述】:
我想要一个执行以下操作的存储过程:
锁定表
检查其中的值
根据该值更新同一张表
解锁表
如果1到4之间出现错误,表会被解锁吗?还是我需要以某种方式捕获错误? (怎么做?)
有没有更好的方法来做到这一点?
【问题讨论】:
标签: mysql sql stored-procedures
我想要一个执行以下操作的存储过程:
锁定表
检查其中的值
根据该值更新同一张表
解锁表
如果1到4之间出现错误,表会被解锁吗?还是我需要以某种方式捕获错误? (怎么做?)
有没有更好的方法来做到这一点?
【问题讨论】:
标签: mysql sql stored-procedures
您不能在 MySQL 的存储过程中锁定表。
存储例程中不允许使用 SQL 语句
存储的例程不能包含任意 SQL 语句。不允许使用以下语句:
锁定语句
LOCK TABLES和UNLOCK TABLES。——http://dev.mysql.com/doc/refman/5.6/en/stored-program-restrictions.html
如果您使用的是 InnoDB,那么您可以通过使用 locking reads 和 SELECT ... FOR UPDATE 锁定感兴趣的行来实现您的目的。当您遇到错误并回滚事务时,行会自动解锁。
我在this recent answer 中对此进行了详细介绍,其中的问题涉及避免插入冲突,但无论您是否知道您想要的行已经存在,或者它可能存在或不存在,基本概念都是相同的。
【讨论】:
您是否考虑过使用带有 try-catch 块的事务?看到这个:
BEGIN TRAN
SAVE TRAN S1 -- Savepoint so any rollbacks will only affect this transaction
BEGIN TRY
/* Do your work in here */
END TRY
BEGIN CATCH
ROLLBACK TRAN S1 -- rollback just this transaction
SET @ErrorMessage = ERROR_MESSAGE()
SET @Severity = ERROR_SEVERITY()
SET @State = ERROR_STATE()
RAISERROR(@ErrorMessage, @Severity, @State) -- re-throw error if needed
END CATCH
【讨论】: