本次使用事务方式:
Db.tx(new IAtom() {
public boolean run() throws SQLException {
try {
//用户基本信息
User.dao.insertInfo(basicInfoMap);
//其他信息
Ohter.dao.insertInfo(otherMapList);
} catch (Exception e) {
throw new SQLException("写入信息失败,失败信息!");
}
// 此返回结果 自行判断处理
return true;
}
});
断点查看没有进行自动提交;
/**
* Execute transaction.
* @param config the Config object
* @param transactionLevel the transaction level
* @param atom the atom operation
* @return true if transaction executing succeed otherwise false
*/
boolean tx(Config config, int transactionLevel, IAtom atom) {
Connection conn = config.getThreadLocalConnection();
if (conn != null) { // Nested transaction support
try {
if (conn.getTransactionIsolation() < transactionLevel)
conn.setTransactionIsolation(transactionLevel);
boolean result = atom.run();
if (result)
return true;
throw new NestedTransactionHelpException("Notice the outer transaction that the nested transaction return false"); // important:can not return false
}
catch (SQLException e) {
throw new ActiveRecordException(e);
}
}
Boolean autoCommit = null;
try {
conn = config.getConnection();
autoCommit = conn.getAutoCommit();
config.setThreadLocalConnection(conn);
conn.setTransactionIsolation(transactionLevel);
conn.setAutoCommit(false);
boolean result = atom.run();
//该处断点 没有进行提交 但是数据已经插入。
//数据库也测试了一下 支持事务提交
if (result)
conn.commit();
else
conn.rollback();
return result;
} catch (NestedTransactionHelpException e) {
if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();}
return false;
} catch (Exception e) {
if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();}
throw e instanceof RuntimeException ? (RuntimeException)e : new ActiveRecordException(e);
} finally {
try {
if (conn != null) {
if (autoCommit != null)
conn.setAutoCommit(autoCommit);
conn.close();
}
} catch (Exception e) {
e.printStackTrace(); // can not throw exception here, otherwise the more important exception in previous catch block can not be thrown
} finally {
config.removeThreadLocalConnection(); // prevent memory leak
}
}
}
于是跟踪每一个SQL语句执行:
//其他信息
Ohter.dao.insertInfo(otherMapList);
内部代码:
Db.batch(sqlList, sqlList.size());
private int[] batch(Config config, Connection conn, List<String> sqlList, int batchSize) throws SQLException {
if (sqlList == null || sqlList.size() == 0)
throw new IllegalArgumentException("The sqlList length must more than 0.");
if (batchSize < 1)
throw new IllegalArgumentException("The batchSize must more than 0.");
int counter = 0;
int pointer = 0;
int size = sqlList.size();
int[] result = new int[size];
Statement st = conn.createStatement();
for (int i=0; i<size; i++) {
st.addBatch(sqlList.get(i));
if (++counter >= batchSize) {
counter = 0;
int[] r = st.executeBatch();
//此处进行了 提交,所以导致了外部事务 看似没有生效的问题。。。。
//解决方案就要看,具体业务了,重写批量还是循环处理。。。
conn.commit();
for (int k=0; k<r.length; k++)
result[pointer++] = r[k];
}
}
int[] r = st.executeBatch();
conn.commit();
for (int k=0; k<r.length; k++)
result[pointer++] = r[k];
DbKit.closeQuietly(st);
return result;
}
事务如果无效,1:查看事务是否执行。2:查看数据库表的类型是否支持事务。3:是否有自动提交的SQL封装方法调用。