数据库事务

在数据库中,所谓事务是指一组逻辑操作单元,使数据从一种状态变换到另一种状态。
为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。
事务的操作:先定义开始一个事务,然后对数据作修改操作,这时如果提交(COMMIT),这些修改就永久地保存下来,如果回退(ROLLBACK),数据库管理系统将放弃所作的所有修改而回到开始事务时的状态。

事务的ACID(acid)属性

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

JDBC 事物处理

事务:指构成单个逻辑工作单元的操作集合。
事务处理:保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),要么整个事务回滚(rollback)到最初状态。
当一个连接对象被创建时,默认情况下是自动提交事务:每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚。
为了让多个 SQL 语句作为一个事务执行:
调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务;
在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务;
在出现异常时,调用 rollback(); 方法回滚事务;
若此时 Connection 没有被关闭, 则需要恢复其自动提交状态。

关于事务:
1. 如果多个操作, 每个操作使用的是自己的单独的连接, 则无法保证事务.
2. 具体步骤:
1). 事务操作开始前, 开始事务:取消 Connection 的默认提交行为. connection.setAutoCommit(false);
2). 如果事务的操作都成功,则提交事务: connection.commit();
3). 回滚事务: 若出现异常, 则在 catch 块中回滚事务:

举个例子:

public void testTransaction() {

        Connection connection = null;

        try {

            connection = JDBCTools.getConnection();
System.out.println(connection.getAutoCommit()); // 开始事务: 取消默认提交.
connection.setAutoCommit(false
); String sql = "UPDATE users SET balance = "
+ "balance - 500 WHERE id = 1";
update(connection, sql); int i = 10 / 0;
System.out.println(i); sql = "UPDATE users SET balance = " + "balance + 500 WHERE id = 2";
update(connection, sql); // 提交事务
connection.commit();
} catch (Exception e) {
e.printStackTrace(); // 回滚事务
try {
connection.rollback();
} catch
(SQLException e1) {
e1.printStackTrace();
}

} finally {
JDBCTools.releaseDB(null, null, connection);
}

数据库的隔离机制

对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题:

  脏读: 对于两个事物 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段. 之后, 若 T2 回滚, T1读取的内容就是临时且无效的.
  不可重复读: 对于两个事物 T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段. 之后, T1再次读取同一个字段, 值就不同了.
  幻读: 对于两个事物 T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插入了一些新的行. 之后, 如果 T1 再次读取同一个表, 就会多出几行.
  数据库事务的隔离性: 数据库系统必须具有隔离并发运行各个事务的能力, 使它们不会相互影响, 避免各种并发问题.
一个事务与其他事务隔离的程度称为隔离级别. 数据库规定了多种事务隔离级别, 不同隔离级别对应不同的干扰程度, 隔离级别越高, 数据一致性就越好, 但并发性越弱。

数据库的隔离级别

Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE. Oracle 默认的事务隔离级别为: READ COMMITED。
Mysql 支持 4 中事务隔离级别. Mysql 默认的事务隔离级别为: REPEATABLE READ。

在 MySql 中设置隔离级别

每启动一个 mysql 程序, 就会获得一个单独的数据库连接. 每个数据库连接都有一个全局变量 @@tx_isolation, 表示当前的事务隔离级别. MySQL 默认的隔离级别为 Repeatable Read
查看当前的隔离级别: SELECT @@tx_isolation;
设置当前 mySQL 连接的隔离级别:
set transaction isolation level read committed;
设置数据库系统的全局的隔离级别:
set global transaction isolation level read committed;

代码里面设置隔离级别:

@Test
public void testTransactionIsolationRead() {
String sql = "SELECT balance FROM users WHERE id = 1";
Integer balance = getForValue(sql);
System.out.println(balance);
} // 返回某条记录的某一个字段的值 或 一个统计的值(一共有多少条记录等.)
public <E> E getForValue(String sql, Object... args) { // 1. 得到结果集: 该结果集应该只有一行, 且只有一列
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null; try {
// 1. 得到结果集
connection = JDBCTools.getConnection();
System.out.println(connection.getTransactionIsolation()); // connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); preparedStatement = connection.prepareStatement(sql); for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i + 1, args[i]);
} resultSet = preparedStatement.executeQuery(); if (resultSet.next()) {
return (E) resultSet.getObject(1);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
JDBCTools.releaseDB(resultSet, preparedStatement, connection);
}
// 2. 取得结果 return null;
}

Java -- JDBC 学习--事务的更多相关文章

  1. Java JDBC学习实战(二): 管理结果集

    在我的上一篇博客<Java JDBC学习实战(一): JDBC的基本操作>中,简要介绍了jdbc开发的基本流程,并详细介绍了Statement和PreparedStatement的使用:利 ...

  2. Java JDBC学习实战(三): 事务管理

    一. 数据库的事务特性 事务是一步或多步组成操作序列组成的逻辑执行单元,这个序列要么全部执行,要么则全部放弃执行. 事务的四个特性:原子性(Atomicity).一致性(Consistency).隔离 ...

  3. Java -- JDBC 事务处理, 事务的隔离级别 脏读 不可重复读 等...

    1. 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 数据库开启事务命令 •start transaction 开启事务 •Rollback  回滚事务 •Commit ...

  4. [疯狂Java]JDBC:事务管理、中间点、批量更新

    1. 数据库事务的概念:     1) 事务的目的就是为了保证数据库中数据的完整性.     2) 设想一个银行转账的过程,假设分两步,第一步是A的账户-1000,第二步是B的账户+1000.这两个动 ...

  5. Java -- JDBC 学习--使用 DBUtils

    Apache—DBUtils简介 commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdb ...

  6. Java -- JDBC 学习--批量处理

    批量处理JDBC语句提高处理速度 当需要成批插入或者更新记录时.可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理.通常情况下比单独提交处理更有效率JDBC的批量处理语句包 ...

  7. Java -- JDBC 学习--处理Blob

    Oracle LOB LOB,即Large Objects(大对象),是用来存储大量的二进制和文本数据的一种数据类型(一个LOB字段可存储可多达4GB的数据).LOB 分为两种类型:内部LOB和外部L ...

  8. Java JDBC学习实战(一): JDBC的基本操作

    一.JDBC常用接口.类介绍 JDBC提供对独立于数据库统一的API,用以执行SQL命令.API常用的类.接口如下: DriverManager,管理JDBC驱动的服务类,主要通过它获取Connect ...

  9. Java -- JDBC 学习--通过 ResultSet 执行查询操作

    ResultSet: 结果集. 封装了使用 JDBC 进行查询的结果. 1. 调用 Statement 对象的 executeQuery(sql) 可以得到结果集. 2. ResultSet 返回的实 ...

随机推荐

  1. Linux安装middleBox之prads

    PRADS prads github安装 prads github 项目 prads github命令

  2. Zabbix监控系统部署:基本功能测试

    1. 概述2. 登陆2.1 登陆账号密码2.1 设置中文语言环境3. 创建用户3.1 用户创建入口3.2 添加用户信息3.3 用户报警媒介3.4 用户权限4. 创建监控主机4.1 添加一台监控主机4. ...

  3. centos下升级git版本的操作记录

    在使用git pull.git push.git clone的时候,或者在使用jenkins发版的时候,可能会报类似如下的错误: error: The requested URL returned e ...

  4. Oracle数据库重做日志及归档日志的工作原理说明

    Oracle数据库重做日志及归档日志的工作原理: lgwr进程将redo log buffer中的重做数据写入到redo log中,此时的redo log分组,每当一个redo log group写满 ...

  5. E. Binary Numbers AND Sum

    链接 [http://codeforces.com/contest/1066/problem/E] 题意 给你长度分别为n,m的二进制串,当b>0时,对a,b,&运算,然后b右移一位,把 ...

  6. 《Linux内核分析》第六周学习总结

    <Linux内核分析>第六周学习总结                         ——进程的描述和进程的创建 姓名:王玮怡  学号:20135116 一.理论部分 (一)进程的描述 1 ...

  7. 软件工程APP进度更新

    对原有的界面进行了美化,同时加进了背景音乐,并且优化了算法部分的代码 正在一步一步跟进中 顺带附上上一次组员帮我发的进度地址:http://www.cnblogs.com/case1/p/498192 ...

  8. PAT 甲级 1134 Vertex Cover

    https://pintia.cn/problem-sets/994805342720868352/problems/994805346428633088 A vertex cover of a gr ...

  9. Ubuntu 服务器指南

    https://help.ubuntu.com/lts/serverguide/   Jabber Instant Messaging Server https://help.ubuntu.com/l ...

  10. vue-devtools 的安装和使用

    vue-devtools的安装与使用 一.在github上下载压缩包,github下载地址:https://github.com/vuejs/vue-devtools 二.解压到本地的某盘 三.用你的 ...