0

我使用 mariadb 10.0.20 创建了两个带有 tokudb engine 的表。

table1 structure :
  CREATE TABLE `table1` (
      `id` varchar(28) NOT NULL,
      `tin` varchar(50) DEFAULT NULL,
      `uid` varchar(12) NOT NULL ,
      `process_flag` char(2) DEFAULT NULL,
      `src_db_name` varchar(80),
      `src_tbl` varchar(200) ,
      `sc` varchar(2) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `TIN` (`tin`),  
    ) ENGINE=TokuDB DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED `compression`='tokudb_lzma'

table2 structure:
CREATE TABLE `demo_v12` (  
 `uid` decimal(20,0) NOT NULL,
 `id` varchar(40) NOT NULL,
 PRIMARY KEY (`id`),
) ENGINE=TokuDB DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED `compression`='tokudb_lzma'

我试图使用 JDBC 从 table2 插入到 table1

for(String table2:table2List){
      try (Connection conn = getConnection();
           Statement cst = conn.createStatement();) {
    String query = "insert ignore into table1 (id,uid) select (id,uid) from "+ table2;
    cst.executeUpdate(q);
    }
}

我有数百个表,例如 table2,每个表中有数百万条记录,当我有时在后端看到 show process list 的输出时,我看到“处理事务中止,34752 中有 11264 个”我不明白是否我的插入是否成功完成,有时它会进入死锁情况,它正在重新启动事务并失败。

请让我知道上述错误消息的原因

提前致谢

4

1 回答 1

1

问题是您的代码有问题,因为它不遵循使用 JDBC 的标准方式,特别是因为:

  1. 您在循环内创建连接。永远不要这样做。
  2. 您创建连接而不关闭它们。永远不要这样做。
  3. 您没有正确使用try ... catch语法。

尝试以下操作:

try {
    Connection conn = getConnection();
    Statement cst = conn.createStatement();
    for(String table2:table2List){
        String query = "insert ignore into table1 (id,uid) select (id,uid) from "+ table2;
        cst.executeUpdate(q);
    }
    cst.close();
    conn.close();
    } catch(SQLException se) {
        //Handle errors for JDBC
}

然后,您应该考虑是否只需要整个程序的一个事务或每个操作的一个事务。在第一种情况下,如果某事失败,则不执行任何操作;在第二种情况下,如果某个插入失败,则仅不执行该插入。要获得不同的行为,您应该阅读有关连接属性的手册。autocommit如果您将程序保持原样,autocommit则打开,并且每次插入都是不同的事务。

于 2015-07-07T05:40:01.863 回答