Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL在使用更新案例保存重新排序列表时挂起_Mysql_Sql - Fatal编程技术网

MySQL在使用更新案例保存重新排序列表时挂起

MySQL在使用更新案例保存重新排序列表时挂起,mysql,sql,Mysql,Sql,我正在使用MySQLupdatecase-WHEN-ELSE语句更新web应用程序上的有序列表。我有一个带有sortable拖放插件的html表,在停止事件上,我点击了一个servlet,它将新的顺序保存到MySQL表 问题是,当用户非常快地重新排序表时,MySQL会不时挂起。就像下面的例子一样,在同一秒中发布了4条语句,然后它被挂起 22/01/2014 14:03:25 UPDATE `edited_table_name` SET `order` = CASE NR_DMD WHEN 920

我正在使用
MySQL
updatecase-WHEN-ELSE
语句更新web应用程序上的有序列表。我有一个带有
sortable
拖放
插件的
html表
,在
停止事件
上,我点击了一个
servlet
,它将新的顺序保存到
MySQL表

问题是,当用户非常快地重新排序表时,MySQL会不时挂起。就像下面的例子一样,在同一秒中发布了4条语句,然后它被挂起

22/01/2014 14:03:25 UPDATE `edited_table_name` SET `order` = CASE NR_DMD WHEN 92059 THEN 22 WHEN 124376 THEN 23 WHEN 124163 THEN 24 WHEN 127019 THEN 25 WHEN 123816 THEN 26 WHEN 124348 THEN 27 WHEN 127017 THEN 28 WHEN 126764 THEN 29 WHEN 126637 THEN 30 WHEN 122170 THEN 31 WHEN 125630 THEN 32 WHEN 125515 THEN 33 WHEN 124487 THEN 34 WHEN 124374 THEN 35 WHEN 124343 THEN 36 WHEN 124327 THEN 37 WHEN 126838 THEN 38 WHEN 126720 THEN 39 WHEN 126718 THEN 40 WHEN 123510 THEN 41 WHEN 122966 THEN 42 WHEN 124385 THEN 43 WHEN 122754 THEN 44 WHEN 124312 THEN 45 WHEN 122311 THEN 46 WHEN 121577 THEN 47 WHEN 121028 THEN 48 WHEN 123354 THEN 49 WHEN 121682 THEN 50 WHEN 120993 THEN 51 WHEN 120860 THEN 52 WHEN 120750 THEN 53 WHEN 120460 THEN 54 WHEN 120459 THEN 55 WHEN 120397 THEN 56 WHEN 119178 THEN 57 WHEN 111723 THEN 58 WHEN 127644 THEN 59 WHEN 127610 THEN 60 WHEN 127609 THEN 61 WHEN 127542 THEN 62 WHEN 125799 THEN 63 ELSE order END WHERE NR_DMD IN(92059,124376,124163,127019,123816,124348,127017,126764,126637,122170,125630,125515,124487,124374,124343,124327,126838,126720,126718,123510,122966,124385,122754,124312,122311,121577,121028,123354,121682,120993,120860,120750,120460,120459,120397,119178,111723,127644,127610,127609,127542,125799)
22/01/2014 14:03:25 UPDATE `edited_table_name` SET `order` = CASE NR_DMD WHEN 121419 THEN 10 WHEN 110378 THEN 11 WHEN 124376 THEN 12 WHEN 124163 THEN 13 WHEN 127019 THEN 14 WHEN 123816 THEN 15 WHEN 124348 THEN 16 WHEN 127017 THEN 17 WHEN 126764 THEN 18 WHEN 126637 THEN 19 WHEN 122170 THEN 20 WHEN 125630 THEN 21 WHEN 125515 THEN 22 WHEN 124487 THEN 23 WHEN 124374 THEN 24 WHEN 124343 THEN 25 WHEN 124327 THEN 26 WHEN 126838 THEN 27 WHEN 126720 THEN 28 WHEN 126718 THEN 29 WHEN 123510 THEN 30 WHEN 122966 THEN 31 WHEN 124385 THEN 32 WHEN 122754 THEN 33 WHEN 124312 THEN 34 WHEN 122311 THEN 35 WHEN 121577 THEN 36 ELSE order END WHERE NR_DMD IN(121419,110378,124376,124163,127019,123816,124348,127017,126764,126637,122170,125630,125515,124487,124374,124343,124327,126838,126720,126718,123510,122966,124385,122754,124312,122311,121577)
22/01/2014 14:03:25 UPDATE `edited_table_name` SET `order` = CASE NR_DMD WHEN 127585 THEN 21 WHEN 124376 THEN 22 WHEN 124163 THEN 23 WHEN 127019 THEN 24 WHEN 123816 THEN 25 WHEN 124348 THEN 26 WHEN 127017 THEN 27 WHEN 126764 THEN 28 WHEN 126637 THEN 29 WHEN 122170 THEN 30 WHEN 125630 THEN 31 WHEN 125515 THEN 32 WHEN 124487 THEN 33 WHEN 124374 THEN 34 WHEN 124343 THEN 35 WHEN 124327 THEN 36 WHEN 126838 THEN 37 WHEN 126720 THEN 38 WHEN 126718 THEN 39 WHEN 123510 THEN 40 WHEN 122966 THEN 41 WHEN 124385 THEN 42 WHEN 122754 THEN 43 WHEN 124312 THEN 44 WHEN 122311 THEN 45 WHEN 121577 THEN 46 WHEN 121028 THEN 47 WHEN 123354 THEN 48 WHEN 121682 THEN 49 WHEN 120993 THEN 50 WHEN 120860 THEN 51 WHEN 120750 THEN 52 WHEN 120460 THEN 53 WHEN 120459 THEN 54 WHEN 120397 THEN 55 WHEN 119178 THEN 56 WHEN 111723 THEN 57 WHEN 127644 THEN 58 WHEN 127610 THEN 59 WHEN 127609 THEN 60 ELSE order END WHERE NR_DMD IN(127585,124376,124163,127019,123816,124348,127017,126764,126637,122170,125630,125515,124487,124374,124343,124327,126838,126720,126718,123510,122966,124385,122754,124312,122311,121577,121028,123354,121682,120993,120860,120750,120460,120459,120397,119178,111723,127644,127610,127609)
22/01/2014 14:03:25 UPDATE `edited_table_name` SET `order` = CASE NR_DMD WHEN 127638 THEN 19 WHEN 127592 THEN 20 WHEN 124376 THEN 21 WHEN 124163 THEN 22 WHEN 127019 THEN 23 WHEN 123816 THEN 24 WHEN 124348 THEN 25 WHEN 127017 THEN 26 WHEN 126764 THEN 27 WHEN 126637 THEN 28 WHEN 122170 THEN 29 WHEN 125630 THEN 30 WHEN 125515 THEN 31 WHEN 124487 THEN 32 WHEN 124374 THEN 33 WHEN 124343 THEN 34 WHEN 124327 THEN 35 WHEN 126838 THEN 36 WHEN 126720 THEN 37 WHEN 126718 THEN 38 WHEN 123510 THEN 39 WHEN 122966 THEN 40 WHEN 124385 THEN 41 WHEN 122754 THEN 42 WHEN 124312 THEN 43 WHEN 122311 THEN 44 WHEN 121577 THEN 45 WHEN 121028 THEN 46 WHEN 123354 THEN 47 WHEN 121682 THEN 48 WHEN 120993 THEN 49 WHEN 120860 THEN 50 WHEN 120750 THEN 51 WHEN 120460 THEN 52 WHEN 120459 THEN 53 WHEN 120397 THEN 54 WHEN 119178 THEN 55 WHEN 111723 THEN 56 WHEN 127644 THEN 57 ELSE order END WHERE NR_DMD IN(127638,127592,124376,124163,127019,123816,124348,127017,126764,126637,122170,125630,125515,124487,124374,124343,124327,126838,126720,126718,123510,122966,124385,122754,124312,122311,121577,121028,123354,121682,120993,120860,120750,120460,120459,120397,119178,111723,127644)
我以为MySQL会处理同一张表上的同时点击。但看起来不是。也许是表锁的问题

如果你能在任何配置或技术方面给我任何建议,甚至是其他更好的方法来保持重新排序的列表,我将非常感激


谢谢,

我建议您对一段时间的不活动进行检查,当有大量的不活动时,向服务器发送最新更新(具有累积更新)。

您可以在servlet中的update语句之前尝试使用以下会话参数

“将事务隔离级别设置为读取未提交”

这将允许,如果两个语句几乎同时出现,则即使另一个进程没有将其提交给服务器,也将使用最新的语句


当然,如果最终用户在超过X秒(即:2秒)的时间内没有进行任何拖放操作,并且只发送1个请求,则最好只发送更改。也可以解决这个问题。

你会考虑在客户端代码中使用一些东西,这样当列表被重新排序时,你不会同时提交多个Ajax请求,如SETTIMEOUT。 也许是这样的:


在执行更新查询期间,InnoDB会锁定它所遍历的每一行,以查找它正在修改的行。因此,为了减少锁的数量,可以将查询拆分为两个单独的查询:

  • 获取
    PRIMARY\u KEY\u LIST
    ,假设
    edited\u table\u name
    的主键是
    id

    从(…)中的NR\U DMD所在的
    edited\u table\u name
    中选择id

  • 基于主键列表更新

    更新
    编辑的\u表\u名称
    设置
    顺序
    =案例。。。id所在位置(主键列表)

  • 这将减少锁的数量,因为它减少了引擎必须遍历的行数

    另一个选项是在
    NR\u DMD
    列上放置索引

    我可能有一个
    处理程序
    来限制servlet可能在这种情况下受到的影响:

  • 我将把信息/细节存储在一个表中,比如说
    new\u order\u requests\u table
    ,而不是立即应用到达servlet的每个新订单请求
  • 我将有一个
    标志,该标志将由该处理程序使用/更新,并相应地显示其自身的状态,例如:
    Idle
    Under Progress
    ,等等
  • 每当上面的代码>标志< /代码>显示为<代码>空闲< /代码>时,我会考虑从<代码> NeXyOrrordRealestsx表< /代码>中应用最新行,并可能从中删除所有较早的行。
  • 对于多个用户,您需要相应地修改上述内容

    此外,当需要在一条语句中更新MySQL表中的许多行时,有时使用MyISAM进行表级锁定比使用InnoDB进行行级锁定更好。这是因为InnoDB可能会花费相当长的时间来锁定和解锁这些行。

    您可以尝试在
    MyISAM
    InnoDB
    之间切换,以便在应用程序中找到更适合此表的引擎


    我认为你可以做到以下几点:

    CREATE TEMPORARY TABLE Table1 (
         NR_DMD int NOT NULL);
    
    INSERT INTO Table1 (NR_DMD)
       VALUES
    (92059),(124376),(124163),(127019),(123816),(124348),(127017),(126764),(126637),
    (122170),(125630),(125515),(124487),(124374),(124343),(124327),(126838),(126720),
    (126718),(123510),(122966),(124385),(122754),(124312),(122311),(121577),(121028),
    (123354),(121682),(120993),(120860),(120750),(120460),(120459),(120397),(119178),
    (111723),(127644),(127610),(127609),(127542),(125799);
    
    select * from Table1
    
    22/01/2014 14:03:25 
    UPDATE `edited_table_name
    ` SET `order` = CASE NR_DMD WHEN 92059 THEN 22 WHEN 124376 THEN 23 WHEN 124163 THEN 24 
    WHEN 127019 THEN 25 WHEN 123816 THEN 26 WHEN 124348 THEN 27 WHEN 127017 THEN 28
    WHEN 126764 THEN 29 WHEN 126637 THEN 30 WHEN 122170 THEN 31
    WHEN 125630 THEN 32 WHEN 125515 THEN 33 WHEN 124487 THEN 34 
    WHEN 124374 THEN 35 WHEN 124343 THEN 36 WHEN 124327 THEN 37 
    WHEN 126838 THEN 38 WHEN 126720 THEN 39 WHEN 126718 THEN 40
    WHEN 123510 THEN 41 WHEN 122966 THEN 42 WHEN 124385 THEN 43 
    WHEN 122754 THEN 44 WHEN 124312 THEN 45 WHEN 122311 THEN 46
    WHEN 121577 THEN 47 WHEN 121028 THEN 48 WHEN 123354 THEN 49
    WHEN 121682 THEN 50 WHEN 120993 THEN 51 WHEN 120860 THEN 52 
    WHEN 120750 THEN 53 WHEN 120460 THEN 54 WHEN 120459 THEN 55
    WHEN 120397 THEN 56 WHEN 119178 THEN 57 WHEN 111723 THEN 58 
    WHEN 127644 THEN 59 WHEN 127610 THEN 60 WHEN 127609 THEN 61 
    WHEN 127542 THEN 62 WHEN 125799 THEN 63 ELSE order END 
    WHERE NR_DMD IN(Select NR_DMD from Table1);
    
    摘要:

    1) 创建临时表并插入第一次更新的值

    (二)

    3) 对另外两条update语句执行相同的操作


    我认为这将有助于您更好地执行。

    您是否遇到错误1100:表已锁定?另外,您是否尝试过在每个
    更新之间解锁表这将有助于确定它是否是由表被锁定引起的。另外,您使用的是innodb还是myisam?好吧,我没有在JDBC上发现任何错误。至少它没有到达JDBC。我将检查MySQL日志。表的引擎是InnoDB。当有锁时,请运行命令SHOW InnoDB STATUS和SHOW FULL PROCESS LIST from 2个其他会话。这应该告诉我们发生了什么。我不认为这是一个不活动的问题,因为该表是针对几乎没有空闲时间的应用程序的各种功能读取的。我的意思是,您应该维护用户对不活动的检查,以修复应该进入数据库的更改。用户完成更改后,可以将其反映到数据库中。现在,为了确定用户已经完成了更改,现在只需检查所需UI元素中是否处于非活动状态,然后将更改发送到数据库。这不会使问题恶化吗?在READ COMMITTED中,与扫描不匹配的锁将在语句完成后释放。确保关闭语句并使用适当的索引,因为innodb可能会锁定比所选行更多的行。。使用“ShowEngineInnoDB状态”将显示它使用了多少锁。。。它应该与NR_DMD where子句中的项目数相匹配。。这样做会很糟糕,因为它会锁定21878行,但只更新了1行(撤消日志条目1)。。。但218k行被锁定。633 lock struct,堆大小96696,218786行锁,撤消日志条目1还有一个附带说明,您可能希望尝试删除“order”上的索引,因为在更新过程中innodb可能会锁定索引…NR_DMD是主键如果NR_DMD是主键,则更新查询违反
    
    UPDATE tablename SET ColName =CASE STATEMENT
           Where NR_DMD in ( SELECT NR_DMD FROM temp table)