3.1 异常的使用说明

  1. 在工具类中(JDBCUtils)的方法最好声明异常(throws),以便后续实现类中去捕获这些异常。

    • 工具类中捕获异常通常没有意义 eg:实现类中connection建立过程出现异常,若工具类中使用try-catch则实现类处理异常后后续仍可继续执行,此时后续执行便无意义。
  2. 在实现类中去捕获并处理异常,且可使用fially去将开启的资源(connection, preparedStatement, I/O)关闭

3.2 事务简介

3.2.1 事务&事务处理

  • 事务:一组逻辑操作单元,使数据从一种状态转变为另一种状态
  • 事务处理(事务操作):当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务回滚(rollback)到最初状态。

3.2.2 JDBC事务处理

  • 事务一旦提交就不可回滚

    • 当一个连接对象被创建时,默认情况下是自动提交事务AutoCommit(true):每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚。
    • 关闭数据库连接,数据就会自动的提交。 如果多个操作,每个操作使用的是自己单独的连接,则无法保证事务。即同一个事务的多个操作必须在同一个连接下。

JDBC的事务处理:

  1. 调用Connection对象的setAutoCommit(false)取消自动提交事务
  2. 所有SQL语句执行成功后调用commit()提交事务
  3. 出现异常时在catch里调用rollback()回滚事务
    • 若此时 Connection 没有被关闭,还可能被重复使用,则需要恢复其自动提交状态 setAutoCommit(true)。尤其是在使用数据库连接池技术时,执行close()方法前,建议恢复自动提交状态。

点击查看实例
    @Test//updateRollBack()实现sql语句执行
public void testUpdate(){
Connection connection = null; try {
//1.取消数据的自动提交
connection = JDBCUtils.getConnection();
connection.setAutoCommit(false); String sql1 = "UPDATE account\n" +
"SET balance = balance - 100\n" +
"WHERE id = ?;";
String sql2 = "UPDATE account\n" +
"SET balance = balance + 100\n" +
"WHERE id = ?;"; updateRollBack(connection, sql1, 1); //System.out.println(10 / 0); updateRollBack(connection, sql2, 2); //2.提交数据
connection.commit(); System.out.println("转账成功!");
} catch (Exception e){
e.printStackTrace();
System.out.println("转账失败!"); try {
//3.出现异常数据回滚
connection.rollback();
} catch (Exception e2){
e2.printStackTrace();
}
} finally {
JDBCUtils.closeResource(connection, null);
}
}

3.2.3 事务的四大属性(ACID)

  1. 原子性Atomicity: 过程不可分割

    • 指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
  2. 一致性Consistency: 操作前与操作后总量不变
    • 使数据库从一个一致性状态变换到另外一个一致性状态。
  3. 隔离性Isolation: 多事务操作时,互相不会产生影响
    • 指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  4. 持久性Durability: 事务提交后表中数据发生变化
    • 一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。

3.2.4 数据库的并发问题&隔离级别

1-并发问题

  1. 脏读:读到了已更新而未提交的数据

    • 对于两个事务 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段。之后, 若 T2 回滚, T1读取的内容就是临时且无效的。
  2. 不可重复读: 读到了已更新(update)已提交字段
    • 对于两个事务T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段。之后, T1再次读取同一个字段, 值就不同了。
  3. 幻读: 读到了已插入(insert)已提交字段
    • 对于两个事务T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插入了一些新的行。之后, 如果 T1 再次读取同一个表, 就会多出几行。

2-隔离级别

  • 一个事务与其他事务隔离的程度称为隔离级别,隔离级别越高,数据一致性越好,但并发性越差。
  1. READ UNCOMMITTED(读未提交):允许事务读取其他食物未被提交的变更。允许脏读的出现
  2. READ COMMITTED(读已提交):只允许事务读取已被其他事物提交的变更。不允许脏读,允许可重复读
  3. REPEATABLE READ(可重复读):确保事务可以多此从一个字段中读取相同的值,事务持续期间禁止任何其他事务对这个字段进行更新。 避免脏读和可重复读
  4. SERIALIZABLE(串行化):确保事务可以从一个表中读取相同的行,事务持续期间禁止其他事务对该表进行CUD

3-MySQL中设置隔离级别

  1. 查看当前隔离级别:SELECT @@tx_isolation;
  2. 设置当前MySQL连接隔离级别:set transaction isolation level read committed;
  3. 设置数据库系统的全局隔离级别 : set global transaction isolation level read committed;
  4. 补充
    1. 创建mysql数据库用户:create user tom identified by 'abc123';
    2. 授予权限:
      1. 授予通过网络方式登录的tom用户,对所有库所有表的全部权限,密码设为root

        grant all privileges on *.* to tom@'%' identified by 'root';
      2. 给tom用户使用本地命令行方式,授予user_db这个库下的所有表的插删改查的权限。

        grant select,insert,delete,update on user_db.* to tom@localhost identified by 'abc123';

4-Java中设置隔离级别

  1. 设置隔离级别:connection.setTranscationIsolation(Connection.XXX);
  2. 获取隔离级别:connection.getTransactionIsolation();

点击查看隔离级别测试代码
    @Test
public void select() throws Exception{
Connection connection = JDBCUtils.getConnection(); //获取当前隔离级别
System.out.println(connection.getTransactionIsolation()); //设置隔离级别
connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED); connection.setAutoCommit(false); String sql = "select * from account;";
List<Account> list = AllSelect.getInstance(connection, Account.class, sql);
for(int i = 0; i < list.size(); i++){
System.out.println(list.get(i));
}
} @Test
public void update() throws Exception{
Connection connection = JDBCUtils.getConnection();
String sql = "update account set balance = balance + 100 where id = ?"; connection.setAutoCommit(false); PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setObject(1, 3); preparedStatement.executeUpdate(); //线程休眠15s
Thread.sleep(15000); //回滚测试脏读
connection.rollback(); }

JDBC-3(Transcation) ****的更多相关文章

  1. Java数据库连接技术——JDBC

    大家好,今天我们学习了Java如何连接数据库.之前学过.net语言的数据库操作,感觉就是一通百通,大同小异. JDBC是Java数据库连接技术的简称,提供连接各种常用数据库的能力. JDBC API ...

  2. 玩转spring boot——结合AngularJs和JDBC

    参考官方例子:http://spring.io/guides/gs/relational-data-access/ 一.项目准备 在建立mysql数据库后新建表“t_order” ; -- ----- ...

  3. [原创]java使用JDBC向MySQL数据库批次插入10W条数据测试效率

    使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(100000),如何提高效率呢?在JDBC编程接口中Statement 有两个方法特别值得注意:通过使用addBatch( ...

  4. JDBC MySQL 多表关联查询查询

    public static void main(String[] args) throws Exception{ Class.forName("com.mysql.jdbc.Driver&q ...

  5. JDBC增加删除修改

    一.配置程序--让我们程序能找到数据库的驱动jar包 1.把.jar文件复制到项目中去,整合的时候方便. 2.在eclipse项目右击"构建路径"--"配置构建路径&qu ...

  6. JDBC简介

    jdbc连接数据库的四个对象 DriverManager  驱动类   DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用 ...

  7. JDBC Tutorials: Commit or Rollback transaction in finally block

    http://skeletoncoder.blogspot.com/2006/10/jdbc-tutorials-commit-or-rollback.html JDBC Tutorials: Com ...

  8. FineReport如何用JDBC连接阿里云ADS数据库

    在使用FineReport连接阿里云的ADS(AnalyticDB)数据库,很多时候在测试连接时就失败了.此时,该如何连接ADS数据库呢? 我们只需要手动将连接ads数据库需要使用到的jar放置到%F ...

  9. JDBC基础

    今天看了看JDBC(Java DataBase Connectivity)总结一下 关于JDBC 加载JDBC驱动 建立数据库连接 创建一个Statement或者PreparedStatement 获 ...

  10. Spring学习记录(十四)---JDBC基本操作

    先看一些定义: 在Spring JDBC模块中,所有的类可以被分到四个单独的包:1.core即核心包,它包含了JDBC的核心功能.此包内有很多重要的类,包括:JdbcTemplate类.SimpleJ ...

随机推荐

  1. 入门Kubernetes-StatefulSets

    前言: 前面文中对通过DaemonSet.存储资源对象,实现了在指定节点中运行一个守护进程. 在真实的业务场景中,部署的服务都是有状态的.且有数据需要持久化的:那么如何实现呢? 那么接下来学习一种更加 ...

  2. 题解 y

    传送门 考场上写的记忆化不够快--和暴力一个分 如果题面里有提到类似「从点1出发」的字样,特别注意点1根本就没有连边的情况 这题写记忆化的时候是想搜出所有可能的组合, 那么对于一个点u,剩余深度为d时 ...

  3. C#设计模式---迭代器模式(Iterator Pattern)

    一.目的 提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节. 二.定义 迭代器模式提供了一种方法访问一个聚合对象(理解为集合对象)中各个元素,而又无需暴露该对象的内部表示,这样既可 ...

  4. C语言格式化输出语句

    %d:带符号十进制整数 : %c:单个字符: %s:字符串: %f:6位小数:float; %.2f表示小数点后精确到两位 %lf:6位小数:double;

  5. Object--Date--calendar--System--StringBuilder--基本数据类型包装类型

    Object java.lang.Object类是Java语言中的根类,即所有类的父类 默认toString()方法打印的是对象在堆中的地址值 默认equals()方法比较的也是地址(String中对 ...

  6. 刷题-力扣-107. 二叉树的层序遍历 II

    107. 二叉树的层序遍历 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/binary-tree-level-order-tr ...

  7. 翻译Go Blog: 常量

    常量 Pob Pike 2014年8月24日 原文 介绍 Go是一门静态语言,它不允许不同数字类型间的操作.你不能将一个浮点数(float64)和一个整数(int)相加,也不能将一个32位整数(int ...

  8. 《redis 5设计与源码分析》:第二章 简单动态字符串

    介绍 简单动态字符串(Simple Dynamic Strings, SDS)是Redis的基本数据结构之一,用于存储字符串和整型数据.它的特点是:方便扩容.二进制安全. 二进制安全 在C语言中,用& ...

  9. Visual Studio 2022 预览版3 最新功能解说

    我们很高兴地宣布Visual Studio 2022 的第三个预览版问世啦!预览版3 提供了更多关于个人和团队生产力.现代开发和持续创新等主题的新功能.在本文中,我们将重点介绍Visual Studi ...

  10. MySQL 实例空间使用率过高的原因和解决方法

    用户在使用 MySQL 实例时,会遇到空间使用告警甚至超过实例限额被锁定的情况.在 RDS 控制台的实例基本信息中,即会出现如下信息: 本文将介绍造成空间使用率过高的常见原因及其相应的解决方法.对于M ...