许多数据库的auto-commit默认是ON的,比如MySQL,PostgresSQL等。当然也有默认是OFF的,比如Oracle(Oracle里面执行DML语句是需要手动commit的)。

这里我们以MySQL为例,先写一个基本的JDBC连接的例子:

package com.mycloud.demo.connection;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement; public class ConncetionTest1 { public static void main(String[] args) { String jdbcUrl = "jdbc:mysql://localhost:3306/test_db";
String username = "xxx";
String password = "xxx"; // Basic sample
// Connection -> Statement -> ResultSet: try with resource
try (Connection con = DriverManager.getConnection(jdbcUrl, username, password);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select id, account from test")) {
String result = getResultSetAsString(rs);
System.out.println(result);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("Error occurred!");
}
} private static String getResultSetAsString(ResultSet rs) throws SQLException { ResultSetMetaData rsmd = rs.getMetaData();
int numCols = rsmd.getColumnCount();
StringBuilder sb = new StringBuilder(); while (rs.next()) {
for (int i = 1; i <= numCols; i++) {
String elem = rs.getString(i);
if (rs.wasNull())
sb.append("NULL");
else
sb.append(elem); if (i != numCols)
sb.append("|");
}
sb.append(System.lineSeparator());
} return sb.toString();
}
}

在auto-commit默认是ON的情况下,每一条sql都是一个独立的事务,运行完直接commit。但是如果需要实现事务,比如我们执行一组DML,如果某一条失败,就全部rollback。这种方式就不行了:

        try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password);
Statement stmt = conn.createStatement()) {
stmt.execute("INSERT INTO test(id, account) VALUES (1, 100)");
stmt.execute("INSERT INTO test(id, account) VALUES (2, 200)");
stmt.execute("INSERT INTO test(id, account) VALUES (2, 201)"); // Exception: duplicate pk
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("Error occurred!");
}

我们查询数据库发现,成功插入了两条数据:

id account
1 100
2 200

在这种情况下,我们首先要通过设置connection.setAutoCommit为OFF来开启事务,再通过connection.commit/connection.rollback来提交/回滚事务。

        try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password);
Statement stmt = conn.createStatement()) { conn.setAutoCommit(false);
try {
stmt.execute("INSERT INTO test(id, account) VALUES (1, 100)");
stmt.execute("INSERT INTO test(id, account) VALUES (2, 200)");
stmt.execute("INSERT INTO test(id, account) VALUES (3, 300)");
} catch (SQLException e) {
e.printStackTrace();
conn.rollback(); // rollback
throw e;
}
conn.commit(); // commit } catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("Error occurred!");
}

我们查询数据库发现,成功插入了3条数据:

id account
1 100
2 200
3 300

当然,如果我们去掉conn.commit()这一句,数据就不会插入了。

如果这一组DML中某一条失败,则会被SQLException捕获,从而抛出异常并回滚。

        try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password);
Statement stmt = conn.createStatement()) { conn.setAutoCommit(false);
try {
stmt.execute("INSERT INTO test(id, account) VALUES (1, 100)");
stmt.execute("INSERT INTO test(id, account) VALUES (2, 200)");
stmt.execute("INSERT INTO test(id, account) VALUES (2, 201)"); // Exception: duplicate pk
stmt.execute("INSERT INTO test(id, account) VALUES (3, 300)");
} catch (SQLException e) {
e.printStackTrace();
conn.rollback(); // rollback
throw e;
}
conn.commit(); // commit } catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("Error occurred!");
}

我们再查询数据库发现,并没有数据插入。

最新文章

  1. &quot;当前方法的代码已经过优化,无法计算表达式的值&quot;的这个错误的解决方案!!!
  2. Session的异常
  3. php随机数怎么获取?一个简单的函数就能生成
  4. mate代码详解
  5. cognos8.3 sample在DB2里的安装
  6. Android应用中-更新提示显示红点的方案
  7. char* 和 wchar_t* 如何互相转换
  8. Struts2通过自己定义拦截器实现登录之后跳转到原页面
  9. 一些实用而又记不住的css技巧
  10. sublime安装AngularJS插件
  11. CentOS7自定义系统服务示例
  12. 【.Net Core】处理静态文件
  13. python csv读写
  14. 翻译:group_concat()函数(已提交到MariaDB官方手册)
  15. liunx之Centos6.8杀毒软件的安装
  16. 命令行方式(SSH or powershell )远程windows server
  17. 在centos上搭建JavaWeb环境(jdk+mysql+tomcat)
  18. 解决复制到keil编辑器中汉字出现乱码情况
  19. P2657 [SCOI2009]windy数
  20. IOS中的手势详解

热门文章

  1. Cache 和 Buffer 的区别在哪里
  2. Django REST framework+Vue 打造生鲜电商项目(笔记六)
  3. vmware 共享文件夹不显示文件的问题
  4. HTML怎么块外横向剧中
  5. Planet.Earth.II.EP05.2016
  6. IDEA2018全局搜索中搜索jar包/lib
  7. VTK 简单点云数据显示绘制
  8. 一个类中域(field)的首字母不要大写
  9. 如何在一个function里面设置一个全局的变量?
  10. 【知识点】Java常用类库