IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 07-数据库事务 -> 正文阅读

[大数据]07-数据库事务

数据库事务介绍

  • 事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态。

  • 事务处理(事务操作):保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务**回滚(rollback)**到最初状态。

  • 为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。

事务的ACID属性

名称简介举例
Atomicity原子性所有的SQL语句要么全部成功,要么全部失败,不会存在部分更新。假设有以下场景,A转账100元给B。这里有两个动作:一是A账号减少100元,二是B账号增加100元,这两个动作不可分割。
Consistency一致性事务只能以允许的方式改变受其影响的数据。假设A和B两者的钱加在一起一共100元,那么无论A和B之间如何转账,转几次账,事务结束后两个用户的钱加起来一定还是100元。
Isolation隔离性同时发生的事务(并发事务)不应该导致数据库出于不一致的状态中。系统中每个事务都应该像唯一事务一样执行。任何事务都不应影响其他事务的存在。隔离性即是要达到这样一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
Durability持久性无论数据库或系统是否发生故障,数据都会永久保存在磁盘上,并且不会丢失。当开发人员在使用JDBC操作数据库时,在提交事务后,提示用户事务操作完成,那么这个时候数据就已经存储在磁盘上了。即使数据库重启,该事务所做的更改操作也不会丢失。

数据库的并发问题

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

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

  • 一个事务与其他事务隔离的程度称为隔离级别。数据库规定了多种事务隔离级别, 不同隔离级别对应不同的干扰程度, 隔离级别越高, 数据一致性就越好, 但并发性越弱。

四种隔离级别

  • 数据库提供的4种事务隔离级别:
Read UncommittedRead CommittedRepeatable ReadSerializable
中文名未提交读,读取未提交内容提交读,读取提交内容可重复读可串行化、序列化
简介在该隔离级别,所有的事务都可以看到其他未提交事务的执行结果,即在未提交读级别中,数据的修改,对其他事务也都是可见的,该隔离级别很少用于实际应用。读取未提交的数据,也被称为脏读。该隔离级别最低,并发性能最好。一个事务只能看到已经提交事务所做的改变,换句话说,一个事务从开始到提交之前,所做的任何修改对其他事务都是不可见的。这是大多数数据库系统的默认隔离级别。可重复读可以确保同一个事务,在多次读取同样的数据的时候,得到同样的结果。它解决了脏读的问题,不过理论上,这会导致另一个问题:幻读。这是最高的隔离级别,它通过强制事务排序,强制事务串行执行,使之不可能相互冲突,从而解决幻读问题。换言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。实际应用中也很少用到这种隔离级别,只有在非常需要确保数据一致性而且可以接受没有并发的情况下,才考虑用该级别。这是花费代价最高但是最可靠的事务隔离级别。
脏读支持
不可重复读支持支持
幻读支持支持支持
默认级别数据库Oracle、SQL ServerMySQL
并发性能最高比Read Uncommitted低比Read Committed低最低
  • Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE。 Oracle 默认的事务隔离级别为: READ COMMITED

  • Mysql 支持 4 种事务隔离级别。Mysql 默认的事务隔离级别为: REPEATABLE READ。

在MySql中设置隔离级别

  • 每启动一个 mysql 程序, 就会获得一个单独的数据库连接. 每个数据库连接都有一个全局变量 @@tx_isolation, 表示当前的事务隔离级别。

  • 查看当前的隔离级别:

    SELECT @@tx_isolation;
    
  • 设置当前 mySQL 连接的隔离级别:

    set  transaction isolation level read committed;
    
  • 设置数据库系统的全局的隔离级别:

    set global transaction isolation level read committed;
    
  • 补充操作:

    • 创建mysql数据库用户:

      create user tom identified by 'abc123';
      
    • 授予权限

      #授予通过网络方式登录的tom用户,对所有库所有表的全部权限,密码设为abc123.
      grant all privileges on *.* to tom@'%'  identified by 'abc123'; 
       #给tom用户使用本地命令行方式,授予atguigudb这个库下的所有表的插删改查的权限。
      grant select,insert,delete,update on db_demo.* to tom@localhost identified by 'abc123'; 
      

JDBC事务处理

  • 数据一旦提交,就不可回滚。

  • 数据什么时候意味着提交?

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

    • 调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务
    • 在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务
    • 在出现异常时,调用 rollback(); 方法回滚事务

    若此时 Connection 没有被关闭,还可能被重复使用,则需要恢复其自动提交状态 setAutoCommit(true)。尤其是在使用数据库连接池技术时,执行close()方法前,建议恢复自动提交状态。

案例:用户A向用户B转账100元

import utils.JDBCUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JDBCTransaction {
    public static void main(String[] args) {
        JDBCTransactionDemo();
    }
    public static void JDBCTransactionDemo(){
        Connection conn = null;
        PreparedStatement ps = null;
        try{
            conn = JDBCUtils.GetConnection();
            // 开启事务,关闭自动提交
            conn.setAutoCommit(false);
            // A的账户减少100
            String sqlstr1 = "update user_assets set assets = assets - 100 where user_name = ?";
            ps = conn.prepareStatement(sqlstr1);
            ps.setObject(1,"A");
            ps.execute();
            // B的账户增加100
            String sqlstr2 = "update user_assets set assets = assets + 100 where user_name = ?";
            ps = conn.prepareStatement(sqlstr2);
            ps.setObject(1,"B");
            ps.execute();
            // 如果没有异常,则提交事务
            conn.commit();
        }catch (Exception e){
            e.printStackTrace();
            // 5.若有异常,则回滚事务
            try{
                conn.rollback();
            }catch (SQLException sqlerr){
                sqlerr.printStackTrace();
            }
        }finally {
            try{
                // 恢复每次DML操作的自动提交功能
                conn.setAutoCommit(true);
            }catch (SQLException e){
                e.printStackTrace();
            }
            JDBCUtils.CloseResource(conn,ps);
        }
    }
}

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:49:30  更:2022-04-18 17:52:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:19:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码