处理事务mariadb的中止

时间:2015-07-07 05:12:36

标签: mysql mariadb tokudb

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

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' 我不知道我的插入是否成功完成,有时它会进入死锁状态,重启事务并失败。

请告诉我上述错误消息的原因

非常感谢

1 个答案:

答案 0 :(得分:1)

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

  1. 您在循环内创建连接。 从不这样做。
  2. 您可以创建连接而不关闭它们。 从不这样做。
  3. 您没有正确使用try ... catch语法。
  4. 尝试以下方法:

    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
    }
    

    然后,您应该考虑是否只需要整个程序的一个事务或每个操作的一个事务。在第一种情况下,如果某些内容失败则不执行任何操作,在第二种情况下,如果某个插入失败,则不执行该插入。要获得不同的行为,您应该阅读manual建议连接的autocommit属性。如果您保留程序原样,autocommit处于启用状态,并且每次插入都是不同的交易。