带有事务的过程返回错误1746

时间:2018-01-02 15:06:41

标签: mysql stored-procedures transactions

这是我的程序

use my_database;
drop procedure if exists sel_upd_ports;
delimiter $$
create procedure sel_upd_ports()
begin
    drop temporary table if exists oneone;
    start transaction;
    create temporary table oneone as (select id,tt from table where status=0 limit 10 for update);
    update table a join oneone b on a.id=b.id set status=1;
    commit;
    select * from oneone;
    drop temporary table oneone;
end$$
delimiter ;

这就是我需要的:

  1. 必须是一个程序
  2. 更新+选择查询应该在事务中工作,所以我的应用程序可以并发
  3. 过程应返回结果集
  4. 这个程序有效,但我无法摆脱错误

    ERROR 1746 (HY000): Can't update table 'table' while 'oneone' is being created.
    

    一旦我删除“更新”锁,它就会消失。

1 个答案:

答案 0 :(得分:0)

参见文档:

  

13.2.9 SELECT Syntax

     

...

     

此外,您不能将 FOR UPDATE 用作SELECT的一部分   诸如CREATE TABLE new_table SELECT ... FROM old_table ...之类的陈述。 (如果您尝试这样做,该声明将被拒绝   错误当' new_table '正在进行时,无法更新表' old_table '   创建。)这是MySQL 5.5及更早版本的行为变化,   允许CREATE TABLE ... SELECT语句进行更改   正在创建的表以外的表。

     

...

参见MySQL 5.6发行说明:

  

Changes in MySQL 5.6.2 (2011-04-11, Developer Milestone) :: Bugs Fixed

     
      
  • 不兼容的变化;复制: 不再可能发出CREATE TABLE ... SELECT语句,该语句更改除正在创建的表之外的任何表。任何此类陈述均未执行   而是因错误而失败。

         

    此更改的一个后果是 FOR UPDATE 可能不再存在   完全用于SELECTCREATE TABLE ... SELECT部分。

         

    这意味着,在从先前版本升级之前,您   应该重写导致的任何CREATE TABLE ... SELECT语句   其他表中的更改,以便语句不再这样做。

         

    此更改还会对基于语句的复制产生影响   MySQL 5.6(或更高版本的从属)与运行前一个的主服务器之间的连接   MySQL的版本。在这种情况下,如果是CREATE TABLE ... SELECT   主服务器上导致其他表更改成功的语句   在主人身上,声明仍然在奴隶身上失败,造成了   复制停止。为了防止这种情况发生,你应该这样做   使用基于行的复制,或者之前重写有问题的语句   在主人身上运行它。 (Bug#11749792,Bug#11745361,Bug#39804,   错误#55876)

         

    参考文献:另见:Bug#47899。

  •