最近需要使用jdbc 执行一批SQL,但是一般情况下, 每次只能执行一个SQL语句。
有一些工具类可以帮助我们使用jdbc执行批量的sql。例如 mybatis的 ScriptRunner 和 Spring的 ScriptUtils 工具类;
这里使用 mybatis 的 ScriptRunner 来执行批量的sql;但是发现无法执行回滚操作,不管是不是setAutoCommit 为false。
对源码进行了分析,发现 ScriptRunner 存在一些缺陷,在 mybatis的3.5.9版本。相关代码如下:
private void commitConnection() { try { if (!connection.getAutoCommit()) { connection.commit(); } } catch (Throwable t) { throw new RuntimeSqlException("Could not commit transaction. Cause: " + t, t); } }
如果设置了 setAutoCommit 为true,每执行一个sql提交一次;无法回滚了。
如果设置了setAutoCommit 为false, ScriptRunner 内部又会如上图代码,手动的commit一下; 无法rollback。
因为我这里的需求是:仅仅执行sql去尝试探测,不需要commit, 那就做了一个Connection的代理,屏蔽掉 commit操作
public class NoCommitConnectionProxy extends ConnectionProxy { /** * @param conn 必须设置为 autoCommit为false */ public NoCommitConnectionProxy(Connection conn) { super(conn); } @Override public void commit() throws SQLException { //什么也不做 } }
如此, ScriptRunner 执行的内容就能回滚了。