处理事务 mariadb 的中止
processing abort of transaction mariadb
我使用 mariadb 10.0.20 创建了两个带有 tokudb 引擎的 table。
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);
}
}
我有数百个 tables,如 table2,每个 table 中有数百万条记录,有时当我在后端看到 show process list 的输出时,我'我看到 'processing abort of transaction, 11264 out of 34752' 我不明白我的插入是否成功完成,有时它会进入死锁情况,重新启动事务并失败。
请告诉我出现上述错误消息的原因
提前致谢
问题是您的代码有问题,因为它不遵循 JDBC 的标准使用方式,特别是因为:
- 您在循环中创建连接。 永远不要这样做。
- 您创建连接而不关闭它们。 永远不要这样做。
- 您没有正确使用
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
}
那你要考虑是整个程序只需要一个事务,还是每个操作一个事务。在第一种情况下,如果某事失败则什么都不执行,在第二种情况下,如果某个插入失败,则仅不执行该插入。要获得不同的行为,您应该阅读 manual 连接的 autocommit
属性 的提议。如果你让你的程序保持原样,autocommit
开启并且每次插入都是不同的事务。
我使用 mariadb 10.0.20 创建了两个带有 tokudb 引擎的 table。
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 插入到 table1for(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);
}
}
我有数百个 tables,如 table2,每个 table 中有数百万条记录,有时当我在后端看到 show process list 的输出时,我'我看到 'processing abort of transaction, 11264 out of 34752' 我不明白我的插入是否成功完成,有时它会进入死锁情况,重新启动事务并失败。
请告诉我出现上述错误消息的原因
提前致谢
问题是您的代码有问题,因为它不遵循 JDBC 的标准使用方式,特别是因为:
- 您在循环中创建连接。 永远不要这样做。
- 您创建连接而不关闭它们。 永远不要这样做。
- 您没有正确使用
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
}
那你要考虑是整个程序只需要一个事务,还是每个操作一个事务。在第一种情况下,如果某事失败则什么都不执行,在第二种情况下,如果某个插入失败,则仅不执行该插入。要获得不同的行为,您应该阅读 manual 连接的 autocommit
属性 的提议。如果你让你的程序保持原样,autocommit
开启并且每次插入都是不同的事务。