1. 事务

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

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

2. JDBC 的事务支持

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

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

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

  1. // 关闭自动提交,开启事务
  2. void setAutoCommit(boolean autoCommit) throws SQLException;
  3.  
  4. // 提交事务
  5. void commit() throws SQLException;
  6.  
  7. // 回滚事务
  8. void rollback() throws SQLException;

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

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

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

  1. try (Connection conn = Connector.getSqlConnection()) {
  2. conn.setAutoCommit(false);
  3. try (Statement stmt = conn.createStatement()) {
  4. stmt.executeUpdate(sql1);
  5. stmt.executeUpdate(sql2);
  6. } catch (SQLException e1) {
  7. e1.printStackTrace();
  8. }
  9. conn.commit();
  10. } catch (SQLException e) {
  11. e.printStackTrace();
  12. }

3. Savepoint

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

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

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

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

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

  1. package com.gerrard.demo;
  2.  
  3. import com.gerrard.util.Connector;
  4. import com.gerrard.util.DriverLoader;
  5.  
  6. import java.sql.Connection;
  7. import java.sql.SQLException;
  8. import java.sql.Savepoint;
  9. import java.sql.Statement;
  10.  
  11. public final class SavePointDemo {
  12.  
  13. public static void main(String[] args) {
  14. String sql1 = "INSERT INTO STUDENT (STUDENT_NAME, STUDENT_PASSWORD) VALUES ('Ramsey', '999999')";
  15. String sql2 = "INSERT INTO STUDENT (STUDENT_NAME, STUDENT_PASSWORD) VALUES ('Wilshere', '888888')";
  16. // Invalidate SQL
  17. String sql3 = "INSERT INTO STUDENT VALUES(1, 'Ramsey', '999999')";
  18.  
  19. DriverLoader.loadSqliteDriver();
  20. try (Connection conn = Connector.getSqlConnection()) {
  21. conn.setAutoCommit(false);
  22. Savepoint save1 = null;
  23. try (Statement stmt = conn.createStatement()) {
  24. stmt.executeUpdate(sql1);
  25. save1 = conn.setSavepoint();
  26. stmt.executeUpdate(sql2);
  27. stmt.executeUpdate(sql3);
  28. } catch (SQLException e) {
  29. conn.rollback(save1);
  30. }
  31. conn.commit();
  32. } catch (SQLException e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. }

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. SpringMVC+Hibernate框架快速搭建

    1.  新建Maven项目springmvc 2.   pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" ...

  2. Return-to-dl-resolve浅析

    本文介绍一种CTF中的高级rop技巧-Return-to-dl-resolve,不久前的0CTF中的babystack和blackhole就用到了这个技巧. 预备知识 在开始本文前希望大家能预先了解一 ...

  3. PAT (Advanced Level) Practise - 1095. Cars on Campus (30)

    http://www.patest.cn/contests/pat-a-practise/1095 Zhejiang University has 6 campuses and a lot of ga ...

  4. 事件流,事件对象和jQuery

    事件流 多个彼此嵌套元素,他们拥有相同的事件,最内部元素事件被触发后,外边多个元素的同类型事件也会被触发,多个元素他们同类型事件同时执行的效果称为“事件流” 例子:html代码: <div cl ...

  5. 闭包 -------JavaScript

    本文摘要:http://www.liaoxuefeng.com/ 函数作为返回值 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 我们来实现一个对Array的求和.通常情况下,求和的 ...

  6. cf519C. A and B and Team Training(找规律)

    题意 $a$个学生,$b$个教练 可以两个学生和一个教练一组,也可以两个教练和一个学生一组,问最多组成多少组 Sol 发题解的目的是为了纪念一下自己的错误思路 刚开始想的是:贪心的选,让少的跟多的分在 ...

  7. SpringBoot之YAML

    SpringBoot的配置文件有两种,一种是properties结尾的,一种是以yaml或yml文件结尾的 我们讨论一下yml文件结尾的文件: 基本语法: 其实yml文件就是键值对的形式,不过就是键( ...

  8. Centos7之WEB服务器

    1.安装httpd服务 输入命令:yum -y install httpd [root@N37012 ~]# yum -y install httpc Loaded plugins: fastestm ...

  9. Android_组件_Activity基础

    一.概述 Activity是应用组件,提供了用户交互的窗口.一个应用由多个彼此联系的Activity组成.它大多数情况是全屏窗口显示,也可以作为悬浮窗口 或者 多窗口模式. 二.生命周期 下图是来自A ...

  10. 解决国内网络Python2.X 3.X PIP安装模块连接超时问题

    pip国内的一些镜像   阿里云 http://mirrors.aliyun.com/pypi/simple/   中国科技大学 https://pypi.mirrors.ustc.edu.cn/si ...