1. 事务

在关系型数据库中,有一个很重要的概念,叫做事务(Transaction)。它具有 ACID 四个特性:

  • A(Atomicity):原子性,一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
  • C(Consistency):一致性,事务必须是使数据库从一个一致性状态变到另一个一致性状态。
  • I(Isolation):隔离性,一个事务的执行不能被其他事务干扰。
  • D(Durability):持久性,,指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。

2. JDBC 的事务支持

在 JDBC 学习笔记(三)—— JDBC 常用接口和类,JDBC 编程步骤,我曾经提及,JDBC 是使用 Connection 来控制事务的。

Connection 默认使用自动提交策略,即关闭事务,这种情况下,每一条 SQL 语句一旦执行,就会立即提交到数据库,无法回滚。

Connection 提供了以下三个事务相关的接口:

// 关闭自动提交,开启事务
void setAutoCommit(boolean autoCommit) throws SQLException; // 提交事务
void commit() throws SQLException; // 回滚事务
void rollback() throws SQLException;

setAutoCommit(boolean autoCommit) 方法其实做了两件事情:

  • 更改提交策略
  • 开启事务
commit() 方法负责将一个事务内部的所有 SQL 语句一次性提交(全部执行,或者全部不执行)。
rollback() 方法负责回滚事务。
 
对于 rollback,有一点需要特别注意,如果系统遇到一个未处理的 SQLException,程序会自动回滚;反之,如果这个异常被捕获,则需要手动回滚。
 
例如,以下写法无需手动回滚:
try (Connection conn = Connector.getSqlConnection()) {
  conn.setAutoCommit(false);
  try (Statement stmt = conn.createStatement()) {
    stmt.executeUpdate(sql1);
    stmt.executeUpdate(sql2);
  }
  conn.commit();
} catch (SQLException e) {
  e.printStackTrace();

而以下写法则不会自动回滚:

try (Connection conn = Connector.getSqlConnection()) {
conn.setAutoCommit(false);
try (Statement stmt = conn.createStatement()) {
stmt.executeUpdate(sql1);
stmt.executeUpdate(sql2);
} catch (SQLException e1) {
e1.printStackTrace();
}
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}

3. Savepoint

JDBC 另外提供了一个 Savepoint 接口,用来实现事务部分提交。

有时候,我们并不希望一个事务全部执行,或者全部不执行,可能会有这样的需求:

如果执行到某一步出错,回滚的时候返回之前开启事务之后的某一个点。

这时候就需要 Savepoint(这个和 Hiberbate 的隔离级别很类似)。

通过以下示例代码,在执行 sql3 的时候出错,但是由于在执行完 sql1 的时候使用了 Savepoint,所以第一条 SQL 语句的执行结果会保留到数据库中:

package com.gerrard.demo;

import com.gerrard.util.Connector;
import com.gerrard.util.DriverLoader; import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement; public final class SavePointDemo { public static void main(String[] args) {
String sql1 = "INSERT INTO STUDENT (STUDENT_NAME, STUDENT_PASSWORD) VALUES ('Ramsey', '999999')";
String sql2 = "INSERT INTO STUDENT (STUDENT_NAME, STUDENT_PASSWORD) VALUES ('Wilshere', '888888')";
// Invalidate SQL
String sql3 = "INSERT INTO STUDENT VALUES(1, 'Ramsey', '999999')"; DriverLoader.loadSqliteDriver();
try (Connection conn = Connector.getSqlConnection()) {
conn.setAutoCommit(false);
Savepoint save1 = null;
try (Statement stmt = conn.createStatement()) {
stmt.executeUpdate(sql1);
save1 = conn.setSavepoint();
stmt.executeUpdate(sql2);
stmt.executeUpdate(sql3);
} catch (SQLException e) {
conn.rollback(save1);
}
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

JDBC 学习笔记(十一)—— JDBC 的事务支持的更多相关文章

  1. JDBC学习笔记(1)——JDBC概述

    JDBC JDBC API是一个Java API,可以访问任何类型表列数据,特别是存储在关系数据库中的数据.JDBC代表Java数据库连接. JDBC库中所包含的API任务通常与数据库使用: 连接到数 ...

  2. 【转】JDBC学习笔记(1)——JDBC概述

    转自:http://www.cnblogs.com/ysw-go/ JDBC JDBC API是一个Java API,可以访问任何类型表列数据,特别是存储在关系数据库中的数据.JDBC代表Java数据 ...

  3. JDBC学习笔记之JDBC简介

    1. 引言 JDBC API是一种Java API,可以访问任何类型的表格数据,特别是存储在关系数据库中的数据. JDBC可以帮助我们编写下列三种编程活动的java应用程序: 1.连接到数据源,如数据 ...

  4. JDBC学习笔记一

    JDBC学习笔记一 JDBC全称 Java Database Connectivity,即数据库连接,它是一种可以执行SQL语句的Java API. ODBC全称 Open Database Conn ...

  5. JDBC 学习笔记(六)—— PreparedStatement

    1. 引入 PreparedStatement PreparedStatement 通过 Connection.createPreparedStatement(String sql) 方法创建,主要用 ...

  6. JDBC学习笔记二

    JDBC学习笔记二 4.execute()方法执行SQL语句 execute几乎可以执行任何SQL语句,当execute执行过SQL语句之后会返回一个布尔类型的值,代表是否返回了ResultSet对象 ...

  7. JDBC 学习笔记(十)—— 使用 JDBC 搭建一个简易的 ORM 框架

    1. 数据映射 当我们获取到 ResultSet 之后,显然这个不是我们想要的数据结构. 数据库中的每一个表,在 Java 代码中,一定会有一个类与之对应,例如: package com.gerrar ...

  8. Go语言学习笔记十一: 切片(slice)

    Go语言学习笔记十一: 切片(slice) 切片这个概念我是从python语言中学到的,当时感觉这个东西真的比较好用.不像java语言写起来就比较繁琐.不过我觉得未来java语法也会支持的. 定义切片 ...

  9. python3.4学习笔记(十一) 列表、数组实例

    python3.4学习笔记(十一) 列表.数组实例 #python列表,数组类型要相同,python不需要指定数据类型,可以把各种类型打包进去#python列表可以包含整数,浮点数,字符串,对象#创建 ...

随机推荐

  1. 运维自动化之Cobbler系统安装详解

    原文链接 参考文档 参考文档SA们现在都知道运维自动化的重要性,尤其是对于在服务器数量按几百台.几千台增加的公司而言,单单是装系统,如果不通过自动化来完成,根本是不可想象的. 运维自动化安装方面,早期 ...

  2. JQuery从服务器端取得数据绑定到dropdownlist(select)中

    http://blog.csdn.net/gaofang2009/article/details/5840783 http://www.cnblogs.com/Mac_Hui/archive/2010 ...

  3. primeng 中 pickList组件的使用

    primeng 是为angular 开发的一个强大的组建库,有很多强大的功能,拿来即用.但要真正满足自己的业务需求,就是按自己的需求进行修改,比如默认的样式等等. 进入正题. pickList 组件的 ...

  4. iOS开发——应用间跳转

    iOS开发过程中,我们经常碰到应用间跳转的情景: 1.使用第三方用户登录,跳转到需授权的App或跳转到分享app的对应页面 *需要用户授权,还需要"返回到调用的程序,同时返回授权的用户名.密 ...

  5. 【前端_js】解决ajax跨域请求数据

    1.ajax发送请求必须遵循同源策略,即请求方和相应方的协议头.域名.端口全部一样.只要三者有一个不一样都视为跨域,浏览器出于安全考虑不允许跨域访问. 解决ajax跨域访问的常用方法: a.使用jso ...

  6. ZendFramework-2.4 源代码 - 关于MVC - Model层

    所谓的谓词Predicate // ------ 所谓的谓词 ------ // 条件 case.3 $where = new \Zend\Db\Sql\Where(); $expression = ...

  7. 从源码带你看懂functools的partial方法

    1.what? partial是什么, partial也叫偏函数.源码的描述是: 部分应用给定参数和关键字的新函数. New function with partial application of ...

  8. python flask学习第1天

    flask安装: 第一个flask程序: 用pycharm新建一个flask项目,新建项目的截图如下: app.py代码如下: #从flask这个包中导入Flask这个类 #Flask这个类是项目的核 ...

  9. B1066 图像过滤 (15分)

    B1066 图像过滤 (15分) 图像过滤是把图像中不重要的像素都染成背景色,使得重要部分被凸显出来.现给定一幅黑白图像,要求你将灰度值位于某指定区间内的所有像素颜色都用一种指定的颜色替换. 输入格式 ...

  10. ACM二分搜索中的最大化最小值 总结

    这类题目都有个相似的地方就是需要你去找一个临界点. 分析题目要你求什么,例如时间 那么mid就是时间 看求得这个跟什么相关 例如 poj 3258 求得是距离 这个距离跟两者之间的差相关 那题目要求你 ...