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. POJ 2229 Sumsets(递推,找规律)

    构造,递推,因为划分是合并的逆过程,考虑怎么合并. 先把N展开成全部为N个1然后合并,因为和顺序无关,所以只和出现次数有关情况有点多并且为了避免重复,分类,C[i]表示序列中最大的数为2^i时的方案数 ...

  2. 2017.12.14 Java实现-----图书管理系统

    通过对图书的增删改查操作 用数组实现 Manager类 package demo55; import java.util.*; public class Manager { Scanner sc = ...

  3. 张量 (tensor) 是什么?

    对于大部分已经熟练的数学和物理工作者, 这实在是一个极为基础的问题. 但这个问题在我刚接触张量时也困扰了我很久. 张量的那么多定义, 究竟哪些是对的? (显然都是对的. ) 它们的关系是什么? 我尽可 ...

  4. NSCopying

    ///< .h @interface ChatManager : NSObject <NSCopying> @property (nonatomic) NSUInteger inde ...

  5. 该网页无法正常运作 目前无法处理此请求HTTP ERROR 500?

    由于php.ini配置文件中错误显示关闭导致. 将下值由Off 变更为 On display_errors = On display_startup_errors = On

  6. Python_装饰器、迭代器、生成器

    一.装饰器 装饰器的存在是为了实现开放封闭原则: 封闭: 已实现的功能代码块不应该被修改: 开放: 对现有功能的扩展开放. 理解装饰器的三要素: 函数的作用域 高阶函数 闭包 1. 闭包 闭包定义:如 ...

  7. WebSocket 详解

    WebSocket 出现前 构建网络应用的过程中,我们经常需要与服务器进行持续的通讯以保持双方信息的同步.通常这种持久通讯在不刷新页面的情况下进行,消耗一定的内存资源常驻后台,并且对于用户不可见.在 ...

  8. API Star:一个 Python 3 的 API 框架

    为了在 Python 中快速构建 API,我主要依赖于 Flask.最近我遇到了一个名为 "API Star" 的基于 Python 3 的新 API 框架.由于几个原因,我对它很 ...

  9. day03_基本数据类型基本运算

    1.什么是数据类型 变量值才是我们存储的数据,所以数据类指的就是变量值的不同种类 2.为何数据要分类型? 变量值是用来保存现实世界中的状态的,那么针对不同的状态就应该用不同类型的数据去表示 3.如何用 ...

  10. javascript简易日历制作

    学习记录 01.练习数组的用法 02.理解this.index的用法 03.绑定事件深入练习理解 html代码 <div id="date"> <ul id=&q ...