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 3057 Evacuation(二分匹配)

    分析: 这是一个时间和门的二元组(t,d)和人p匹配的问题,当我们固定d0时,(t,d0)匹配的人数和t具有单调性. t增加看成是多增加了边就行了,所以bfs处理出p到每个d的最短时间,然后把(t,d ...

  2. 从用户访问网站流程开始,细说web网络基础

    1.用户访问网站流程框架 2.dns解析原理 3.tcp/ip三次握手过程原理,11种连接状态 4.tcp/ip四次挥手过程原理,11种连接状态 5.http协议原理(www服务的请求过程)请求细节, ...

  3. flash + php对称密钥加密的交互

    这几天研究了下php和flash中的对称密钥加密的交互问题,经过研究以后决定,在项目中使用aes加密.问题也就来了,在flash中的加密数据如何与php的amf进行数据交互,最终决定使用base64编 ...

  4. Ubuntu 上配置静态的ip

    先关掉或卸掉 network-manager.然后,改动/etc/network/interfaces 如下:(由于是静态ip,你当然知道把例子中那些东西改成你自己的)auto lo eth0ifac ...

  5. 获取Bing每日壁纸用作首屏大图

    获取Bing每日壁纸用作首屏大图 Bing 搜索每天都会更换一张精美的图片作为壁纸,除了特殊时候不太好看外(比如春节那几天),没多大问题.移动端还有上每日故事,与图片现配.现在我的博客首屏图片就是Bi ...

  6. java基础面试题:说说&和&&的区别

    &与&&都是逻辑与 不同的是&左右两边的判断都要进行,而&&是短路与,当&&左边条件为假则不用再判断右边条件,所以效率更高 例如,对于i ...

  7. PHP添加扩展模块的方法

    进入源码包对应扩展模块目录下 ##extname 代表扩展模块名 cd /usr/local/src/php-5.5.36/ext/extname 然后执行phpize##phpize是一个shell ...

  8. js测试密码的强度

    测试密码的强度.js //网站也会根据输入密码的字符特点给出相应的提示,如密码过短.强度差.强度中等.强度强等. //这又是怎么实现的呢?看下面代码: <input type="pas ...

  9. linux常用指令学习记录

    前言 本文主要为学习贴,用来记录一些 linux上的常用指令 以供参考. 文件内容查看 cat 从上往下阅读文件内容 cat [-AbEnTv] ${FILE_NAME) cat -n /etc/is ...

  10. makefile学习(1)

    GNU Make / Makefile 学习资料 GNU Make学习总结(一) GNU Make学习总结(二) 这篇学习总结,从一个简单的小例子开始,逐步加深,来讲解Makefile的用法. 最后用 ...