Skip to content

Commit e88ddb1

Browse files
committed
Rollback transactions only when an error occurs.
1 parent 1a145cd commit e88ddb1

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed

src/main/java/org/apache/ibatis/jdbc/ScriptRunner.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,9 @@ public void runScript(Reader reader) {
120120
} else {
121121
executeLineByLine(reader);
122122
}
123-
} finally {
123+
} catch (RuntimeSqlException exception) {
124124
rollbackConnection();
125+
throw exception;
125126
}
126127
}
127128

src/test/java/org/apache/ibatis/jdbc/ScriptRunnerTest.java

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
package org.apache.ibatis.jdbc;
1717

1818
import static org.junit.jupiter.api.Assertions.assertEquals;
19+
import static org.junit.jupiter.api.Assertions.assertNotNull;
1920
import static org.junit.jupiter.api.Assertions.assertSame;
21+
import static org.junit.jupiter.api.Assertions.assertThrows;
2022
import static org.junit.jupiter.api.Assertions.assertTrue;
2123
import static org.junit.jupiter.api.Assertions.fail;
2224
import static org.mockito.Mockito.mock;
@@ -282,4 +284,93 @@ void shouldAcceptMultiCharDelimiter() throws Exception {
282284
verify(stmt).execute("line 1;" + LINE_SEPARATOR + "line 2;" + LINE_SEPARATOR + LINE_SEPARATOR);
283285
verify(stmt).execute("line 3" + LINE_SEPARATOR);
284286
}
287+
288+
@Test
289+
void testRollbackWithAutoCommitFalseAndStopErrorTrue() throws Exception {
290+
DataSource ds = createJPetstoreDataSource();
291+
try (Connection conn = ds.getConnection()) {
292+
ScriptRunner runner = new ScriptRunner(conn);
293+
runner.setAutoCommit(false);
294+
runner.setStopOnError(true);
295+
runner.setSendFullScript(false);
296+
Reader reader = new StringReader("""
297+
INSERT INTO signon VALUES('xiaoai','123456');
298+
123;
299+
INSERT INTO signon VALUES('xiaolan','123456');
300+
""");
301+
assertThrows(RuntimeSqlException.class, () -> runner.runScript(reader));
302+
}
303+
assertSignonCountByUsername(ds, "xiaoai", 0L);
304+
assertSignonCountByUsername(ds, "xiaolan", 0L);
305+
}
306+
307+
@Test
308+
void testRollbackWithAutoCommitFalseAndStopErrorFalse() throws Exception {
309+
DataSource ds = createJPetstoreDataSource();
310+
try (Connection conn = ds.getConnection()) {
311+
ScriptRunner runner = new ScriptRunner(conn);
312+
runner.setAutoCommit(false);
313+
runner.setStopOnError(false);
314+
runner.setSendFullScript(false);
315+
Reader reader = new StringReader("""
316+
INSERT INTO signon VALUES('xiaoai','123456');
317+
123;
318+
INSERT INTO signon VALUES('xiaolan','123456');
319+
""");
320+
runner.runScript(reader);
321+
}
322+
assertSignonCountByUsername(ds, "xiaoai", 1L);
323+
assertSignonCountByUsername(ds, "xiaolan", 1L);
324+
}
325+
326+
private void assertSignonCountByUsername(DataSource dataSource, String username, long expectedVal)
327+
throws SQLException {
328+
try (Connection conn = dataSource.getConnection()) {
329+
Map<String, Object> map = new SqlRunner(conn).selectOne("select count(*) as COUNT from signon where username = ?",
330+
username);
331+
assertNotNull(map);
332+
assertNotNull(map.get("COUNT"));
333+
assertEquals(expectedVal, map.get("COUNT"));
334+
}
335+
}
336+
337+
@Test
338+
void testRollbackWithAutoCommitTrueAndStopErrorTrue() throws Exception {
339+
DataSource ds = createJPetstoreDataSource();
340+
try (Connection conn = ds.getConnection()) {
341+
ScriptRunner runner = new ScriptRunner(conn);
342+
runner.setAutoCommit(true);
343+
runner.setStopOnError(true);
344+
runner.setErrorLogWriter(null);
345+
runner.setSendFullScript(false);
346+
Reader reader = new StringReader("""
347+
INSERT INTO signon VALUES('xiaohong','123456');
348+
123;
349+
INSERT INTO signon VALUES('xiaoming','123456');
350+
""");
351+
assertThrows(RuntimeSqlException.class, () -> runner.runScript(reader));
352+
}
353+
assertSignonCountByUsername(ds, "xiaohong", 1L);
354+
assertSignonCountByUsername(ds, "xiaoming", 0L);
355+
}
356+
357+
@Test
358+
void testRollbackWithAutoCommitTrueAndStopErrorFalse() throws Exception {
359+
DataSource ds = createJPetstoreDataSource();
360+
try (Connection conn = ds.getConnection()) {
361+
ScriptRunner runner = new ScriptRunner(conn);
362+
runner.setAutoCommit(true);
363+
runner.setStopOnError(false);
364+
runner.setErrorLogWriter(null);
365+
runner.setSendFullScript(false);
366+
Reader reader = new StringReader("""
367+
INSERT INTO signon VALUES('xiaohong','123456');
368+
123;
369+
INSERT INTO signon VALUES('xiaoming','123456');
370+
""");
371+
runner.runScript(reader);
372+
}
373+
assertSignonCountByUsername(ds, "xiaohong", 1L);
374+
assertSignonCountByUsername(ds, "xiaoming", 1L);
375+
}
285376
}

0 commit comments

Comments
 (0)