AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 29243
Accepted
Adam Matan
Adam Matan
Asked: 2012-11-26 01:46:18 +0800 CST2012-11-26 01:46:18 +0800 CST 2012-11-26 01:46:18 +0800 CST

jdbc+mysql:“尝试获取锁时发现死锁;尝试重新启动事务”

  • 772

从磁盘已满问题中恢复后,我的日志中开始出现以下错误:

java.sql.BatchUpdateException: Deadlock found when trying to get lock; try restarting transaction
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1684)
    at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1108)
    at com.dappit.Dapper.adminer.pixelMaster.storage.RemotePixelStorage.flushBufferToDb(RemotePixelStorage.java:120)
    ...

Java 代码(RemotePixelStorage.java:120):

(119) connection.setAutoCommit(false);
(120) int[] returnCodes = pstmt.executeBatch();
(121) connection.setAutoCommit(true);
(122) connection.commit();

每个语句都是对存储过程add_pixel的调用,它将向表中添加一个元素并在必要时删除旧元素。

这个jdbc异常是什么意思?我该如何克服这个问题?我是否应该尝试使用 catch 块提交几次?

mysql innodb
  • 2 2 个回答
  • 7890 Views

2 个回答

  • Voted
  1. Best Answer
    RolandoMySQLDBA
    2012-12-20T10:31:16+08:002012-12-20T10:31:16+08:00

    查看存储过程,我看到了一些相当不自然的东西。

    DELIMITER $$
    
    DROP PROCEDURE IF EXISTS `adam_matan`.`AddPixel` $$
    CREATE PROCEDURE `adam_matan`.`AddPixel`
    (
        GivenType VARCHAR(20),
        GivenPixelData BLOB
    )
    TheStoredProcedure:BEGIN
    
      DECLARE KeepPixels,DeleteLimit,MaxID INT;
    
      SET KeepPixels = 5;
      SET DeleteLimit = 100;
    
      INSERT INTO pixels (type,pixel_data)
      VALUES (GivenType,GivenPixelData);
      SELECT MAX(ID) INTO MaxID FROM pixels;
      IF MOD(MaxID,DeleteLimit) > 0 THEN
          LEAVE TheStoredProcedure;
      END IF;
    
      DROP TABLE IF EXISTS pixel_window;
      CREATE TEMPORARY TABLE pixel_window
      (id INT NOT NULL PRIMARY KEY) ENGINE=MyISAM;
    
      SET @sqlstmt= CONCAT('INSERT INTO pixel_window ',
          'SELECT id FROM pixels WHERE type=''',GivenType,
          ''' ORDER BY id DESC LIMIT ',KeepPixels);
      PREPARE st FROM @sqlstmt; EXECUTE st; DEALLOCATE PREPARE st;
    
      SELECT * FROM pixels WHERE type=GivenType ORDER BY id; SELECT SLEEP(10);
      DELETE A.* FROM pixels A LEFT JOIN pixel_window B USING (id)
      WHERE A.type=GivenType AND B.id IS NULL;
      SELECT * FROM pixels WHERE type=GivenType ORDER BY id;
      DROP TABLE IF EXISTS pixel_window;
    
    END $$
    
    DELIMITER ;
    

    我看到的不自然的事情DELETE ... JOIN是混合 InnoDB 表和 MyISAM 表的查询。这样的 JOIN 对 mysqld 来说往往比较笨拙。

    让我们做pixel_window桌子。创新数据库。事实上,我们不要让它成为一个临时表。当然,困难的部分是pixel_window为会话创建一个唯一的表。pixel_window 临时表的前缀为“pixel_window_”,并附加了连接 ID。

    DELIMITER $$
    
    DROP PROCEDURE IF EXISTS `adam_matan`.`AddPixel` $$
    CREATE PROCEDURE `adam_matan`.`AddPixel`
    (
        GivenType VARCHAR(20),
        GivenPixelData BLOB
    )
    TheStoredProcedure:BEGIN
    
      DECLARE KeepPixels,DeleteLimit,MaxID INT;
    
      SET KeepPixels = 5;
      SET DeleteLimit = 100;
    
      INSERT INTO pixels (type,pixel_data)
      VALUES (GivenType,GivenPixelData);
      SELECT MAX(ID) INTO MaxID FROM pixels;
      IF MOD(MaxID,DeleteLimit) > 0 THEN
          LEAVE TheStoredProcedure;
      END IF;
    
      SET @pwtable = CONCAT('pixel_window_',CONNECTION_ID());
    
      #
      # Create the pixel_window Table
      #
      SET @sqlstmt = CONCAT('CREATE TABLE ',pwtable,' (id INT NOT NULL PRIMARY KEY) ENGINE=InnoDB');
      PREPARE st FROM @sqlstmt; EXECUTE st; DEALLOCATE PREPARE st;
    
      #
      # Load the pixel_window Table
      #
      SET @sqlstmt= CONCAT('INSERT INTO ',@pwtable,' ',
          'SELECT id FROM pixels WHERE type=''',GivenType,
          ''' ORDER BY id DESC LIMIT ',KeepPixels);
      PREPARE st FROM @sqlstmt; EXECUTE st; DEALLOCATE PREPARE st;
    
      SELECT * FROM pixels WHERE type=GivenType ORDER BY id; SELECT SLEEP(10);
    
      #
      # Use the pixel_window Table to perform DELETE...JOIN
      #
      SET @sqlstmt = CONCAT('DELETE A.* FROM pixels A LEFT JOIN ',
      @pwtable,' B USING (id) WHERE A.type=GivenType AND B.id IS NULL');
      PREPARE st FROM @sqlstmt; EXECUTE st; DEALLOCATE PREPARE st;
    
      SELECT * FROM pixels WHERE type=GivenType ORDER BY id;
    
      #
      # Drop the pixel_window Table
      #
      SET @sqlstmt = CONCAT('DROP TABLE IF EXISTS ',@pwtable);
      PREPARE st FROM @sqlstmt; EXECUTE st; DEALLOCATE PREPARE st;
    
    END $$
    
    DELIMITER ;
    

    试试看 !!!

    CAVEAT:既然我创造了这个怪物,我也需要杀死它。

    • 1
  2. ArrowInTree
    2012-12-20T06:07:41+08:002012-12-20T06:07:41+08:00

    您说您刚刚从“磁盘已满”状态中恢复过来。
    您也从未说过其他哪些进程/程序访问这些数据。
    我们需要枚举其他访问程序,因为它们可能是死锁的根源。

    请记住,死锁意味着竞争访问,尤其是对于写入。
    现在……考虑一下您的ACID品质:原子性、一致性、耐用性和隔离性……

    • 0

相关问题

  • 是否有任何 MySQL 基准测试工具?[关闭]

  • 我在哪里可以找到mysql慢日志?

  • 如何优化大型数据库的 mysqldump?

  • 什么时候是使用 MariaDB 而不是 MySQL 的合适时机,为什么?

  • 组如何跟踪数据库架构更改?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何查看 Oracle 中的数据库列表?

    • 8 个回答
  • Marko Smith

    mysql innodb_buffer_pool_size 应该有多大?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    从 .frm 和 .ibd 文件恢复表?

    • 10 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve