事务 commit 与 rollback

笔记/Java/Java 持久层/JDBC/事务 commit 与 rollback

前置:user 表 CRUD

TransactionDemo.java#

package demo.jdbc;
import java.sql.Connection;
import java.sql.SQLException;
public class TransactionDemo {
public static void main(String[] args) throws Exception {
UserDao dao = new UserDao();
try (Connection conn = Db.open()) {
conn.setAutoCommit(false);
try {
transferEmail(conn, dao, "alice", "alice@example.com", "alice.tx@example.com");
conn.commit();
System.out.println("commit ok: alice email updated");
} catch (SQLException ex) {
conn.rollback();
System.out.println("rollback: " + ex.getMessage());
}
try {
transferEmail(conn, dao, "bob", "bob@example.com", "bob@example.com");
forceFail();
conn.commit();
} catch (Exception ex) {
conn.rollback();
System.out.println("rollback expected: " + ex.getMessage());
System.out.println("bob still: " + dao.findById(conn, findIdByName(conn, dao, "bob")).map(User::getEmail));
} finally {
conn.setAutoCommit(true);
}
}
}
private static void transferEmail(Connection conn, UserDao dao, String userName, String expect, String next)
throws SQLException {
long id = findIdByName(conn, dao, userName);
User user = dao.findById(conn, id).orElseThrow();
if (!expect.equals(user.getEmail())) {
throw new SQLException("unexpected email for " + userName);
}
if (dao.updateEmail(conn, id, next) != 1) {
throw new SQLException("update failed for " + userName);
}
}
private static long findIdByName(Connection conn, UserDao dao, String userName) throws SQLException {
for (User u : dao.findByStatus(conn, 1)) {
if (userName.equals(u.getUserName())) {
return u.getId();
}
}
throw new SQLException("user not found: " + userName);
}
private static void forceFail() {
throw new IllegalStateException("simulate business error");
}
}

运行#

Terminal window
mvn -q exec:java -Dexec.mainClass=demo.jdbc.TransactionDemo

要点#

  • setAutoCommit(false) 后,同一 Connection 上的多次 DML 同属一个事务
  • 场景 1:alice 改邮箱 → commit 持久化
  • 场景 2:改 bob 后抛异常 → rollback,邮箱仍为 bob@example.com

Spring @Transactional 底层即为此逻辑,由 DataSourceTransactionManager 绑定连接。

下一篇:JdbcTemplate

文章目录

文章目录