数据库关于事务的详解分析(全)包含面试常问的细节

简介: 目录前言1. 定义2. 特性前言在敲代码的时候,提交事务、事务回滚等,事务二字确官方笼统,不知道具体什么意思这篇文章将为你解答疑惑1. 定义事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务的提交是指事务

前言

在敲代码的时候,提交事务、事务回滚等,事务二字确官方笼统,不知道具体什么意思
这篇文章将为你解答疑惑

具体为什么需要事务
有了事务

事务代表(一组操作,可以是SQL语句或者代码),如果其中一个操作不成功,这些操作都不会执行,前面执行的操作也会回滚原状态,用来保证数据的一致性和完整性。

==保证数据的一致性,保证数据不会出错==

1. 定义

事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。

  • 事务的提交是指事务里的所有操作都正常完成。
  • 事务的回滚是指程序或数据处理错误,将程序或数据恢复到上一次正确状态的行为

2. 四个特性(ACID)

  • 原子性(atomicity)
    要么都成功,要么都失败
  • 一致性(consistency)
    事物前后的数据完整性要保证一致
    比如开始1000块钱,后面转账结束了,也得是1000块钱。
  • 持久性(durability)
    事物一旦提交则不可逆,被持久化到数据库中。
  • 隔离性(isolation)
    事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,

不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离

3. 面临的问题

==并发事务处理带来的问题==

  • 脏读:
    指一个事务读取了另外一个事务未提交的数据。
  • 不可重复读:
    在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误,只是某些场合不对)
  • 虚读(幻读)
    是指在一个事务内读取到了别的事务插入的数据,导致前后读取数量总量不一致

更新丢失(Lost Update)

当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题――最后的更新覆盖了由其他事务所做的更新。

如果在一个程序员完成并提交事务之前,另一个程序员不能访问同一文件,则可避免此问题。

脏读(Dirty Reads)

一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象地叫做”脏读”。

一句话:事务A读取到了事务B已修改但尚未提交的的数据,还在这个数据基础上做了操作。此时,如果B事务回滚,A读取的数据无效,不符合一致性要求。

不可重复读(Non-Repeatable Reads)

一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫做“不可重复读”。

一句话:事务A读取到了事务B已经提交的修改数据,不符合隔离性。

幻读(Phantom Reads)

一个事务接相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读“。

一句话:事务A读取到了事务B体提交的新增数据,不符合隔离性。

多说一句:幻读和脏读有点类似,

脏读是事务B里面修改了数据,

幻读是事务B里面新增了数据。

注意不可重复读和虚度的区别

不可重复读是同一个事务的多次读取而导致信息不一致
虚度是读取到了其他人的信息而导致信息不一致

简单的说:

  • 脏读是事务B里面修改了但未提交的数据,,A读取到了
  • 不可重复读是事务B里面修改了但提交了的数据,A读取到了
  • 幻读是事务B里面新增了但已经提交的数据。,A读取到了

4. 四个隔离级别

”脏读”、“不可重复读”和“幻读”,其实都是数据库读一致性问题,必须由数据库提供一定的事务隔离机制来解决。

读数据—致性及允许的并发副作用(隔离级别) 读数据一致性 脏读 不可重复读 幻读
未提交读(Read Uncommitted) 最低级别,只能保证不读取物理上损坏的数据
已提交读(Read committed) 语句级 否(解决脏读已经提交的问题)
可重复读(Repeatable read) 事务级 否(解决了只读一次的效果)
可序列化(serializable) 最高级别,事务级

在这里插入图片描述

 最高的隔离级别。会强制事务串行执行,简单来说,会在读取(读锁)的每一行数据上都加锁,一般来说在多线程场景下,性能低下。

数据库的事务隔离越严格,并发副作用越小,但付出的代价也就越大,因为事务隔离实质上就是使事务在一定程度上“串行化”进行,这显然与“并发”是矛盾的。同时,不同的应用对读一致性和事务隔离程度的要求也是不同的,比如许多应用对“不可重复读”和“幻读”并不敏感,可能更关心数据并发访问的能力。

  • 常看当前数据库的事务隔离级别:show variables like 'tx_isolation';

系统默认是可重复读

如上表格,可重复读解决了脏读和可重复读的问题,而一般又采用了MVVC多版本并发控制来解决幻读的问题,所以在效率和ACID综合考虑下是相对较好的一个隔离级别选择

5. 四个基本术语

关于事务的四个基本术语

  • 开启事务(Start Transaction)
  • 事务结束(End Transaction)
  • 提交事务(Commit Transaction)
  • 回滚事务(Rollback Transaction)

关于事务的类型

  1. 显示事务

手动提交或回滚;
DML语言所有的操作都是显示事务;

  1. 隐式事务

数据库自动提交,同时不具备回滚性;
DDL、DCL语言都是隐式事务操作

关于DQL、DML、DDL、DCL的区别
可看我之前的文章总结
数据库之DQL、DML、DDL、DCL详细分析

6. 实战

提交事务主要是有改变数据
也就是增删改

public class TestMyBatis {
    //测试方法,测试功能
    @Test
    public void testInsert() throws IOException {

        //访问mybatis读取student数据
        //1.定义mybatis主配置文件的名称, 从类路径的根开始(target/clasess)
        String config="mybatis.xml";
        //2.读取这个config表示的文件
        InputStream in = Resources.getResourceAsStream(config);
        //3.创建了SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder  = new SqlSessionFactoryBuilder();
        //4.创建SqlSessionFactory对象
        SqlSessionFactory factory = builder.build(in);
        //5.获取SqlSession对象,从SqlSessionFactory中获取SqlSession
        SqlSession sqlSession = factory.openSession();
        //SqlSession sqlSession = factory.openSession(true);
        //6.【重要】指定要执行的sql语句的标识。  sql映射文件中的namespace + "." + 标签的id值
        String sqlId = "com.bjpowernode.dao.StudentDao.insertStudent";
        //7. 重要】执行sql语句,通过sqlId找到语句
        Student student  = new Student();
        student.setId(1006);
        student.setName("关羽");
        student.setEmail("guanyu@163.com");
        student.setAge(20);
        int nums = sqlSession.insert(sqlId,student);

        //mybatis默认不是自动提交事务的, 所以在insert ,update ,delete后要手工提交事务
        sqlSession.commit();

        //8.输出结果
        System.out.println("执行insert的结果="+nums);

        //9.关闭SqlSession对象
        sqlSession.close();
    }
}

编译完成之后,需要提交事务才可看到新增加的数据,mybatis默认是没有提交事务

即在insert ,update ,delete后要手工提交事务

//mybatis默认不是自动提交事务的, 所以在insert ,update ,delete后要手工提交事务
        sqlSession.commit();
相关文章
|
2月前
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中如何与事务隔离级别结合使用
乐观锁在分布式数据库中如何与事务隔离级别结合使用
|
2月前
|
负载均衡 NoSQL 算法
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
这篇文章是关于Java面试中Redis相关问题的笔记,包括Redis事务实现、集群方案、主从复制原理、CAP和BASE理论以及负载均衡算法和类型。
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
|
2月前
|
安全 Java 数据库
一天十道Java面试题----第四天(线程池复用的原理------>spring事务的实现方式原理以及隔离级别)
这篇文章是关于Java面试题的笔记,涵盖了线程池复用原理、Spring框架基础、AOP和IOC概念、Bean生命周期和作用域、单例Bean的线程安全性、Spring中使用的设计模式、以及Spring事务的实现方式和隔离级别等知识点。
|
2月前
|
SQL 数据库 数据安全/隐私保护
SQL Server数据库Owner导致事务复制log reader job无法启动的解决办法
【8月更文挑战第14天】解决SQL Server事务复制Log Reader作业因数据库所有者问题无法启动的方法:首先验证数据库所有者是否有效并具足够权限;若非,使用`ALTER AUTHORIZATION`更改为有效登录名。其次,确认Log Reader使用的登录名拥有读取事务日志所需的角色权限。还需检查复制配置是否准确无误,并验证Log Reader代理的连接信息及参数。重启SQL Server Agent服务或手动启动Log Reader作业亦可能解决问题。最后,审查SQL Server错误日志及Windows事件查看器以获取更多线索。
|
21天前
|
存储 关系型数据库 MySQL
【Java面试题汇总】MySQL数据库篇(2023版)
聚簇索引和非聚簇索引、索引的底层数据结构、B树和B+树、MySQL为什么不用红黑树而用B+树、数据库引擎有哪些、InnoDB的MVCC、乐观锁和悲观锁、ACID、事务隔离级别、MySQL主从同步、MySQL调优
【Java面试题汇总】MySQL数据库篇(2023版)
|
2月前
|
缓存 NoSQL Redis
一天五道Java面试题----第九天(简述MySQL中索引类型对数据库的性能的影响--------->缓存雪崩、缓存穿透、缓存击穿)
这篇文章是关于Java面试中可能会遇到的五个问题,包括MySQL索引类型及其对数据库性能的影响、Redis的RDB和AOF持久化机制、Redis的过期键删除策略、Redis的单线程模型为何高效,以及缓存雪崩、缓存穿透和缓存击穿的概念及其解决方案。
|
2月前
|
前端开发 Java 数据库连接
一天十道Java面试题----第五天(spring的事务传播机制------>mybatis的优缺点)
这篇文章总结了Java面试中的十个问题,包括Spring事务传播机制、Spring事务失效条件、Bean自动装配方式、Spring、Spring MVC和Spring Boot的区别、Spring MVC的工作流程和主要组件、Spring Boot的自动配置原理和Starter概念、嵌入式服务器的使用原因,以及MyBatis的优缺点。
|
2月前
|
算法 关系型数据库 MySQL
一天五道Java面试题----第七天(mysql索引结构,各自的优劣--------->事务的基本特性和隔离级别)
这篇文章是关于MySQL的面试题总结,包括索引结构的优劣、索引设计原则、MySQL锁的类型、执行计划的解读以及事务的基本特性和隔离级别。
|
1月前
|
SQL 安全 数据库
基于SQL Server事务日志的数据库恢复技术及实战代码详解
基于事务日志的数据库恢复技术是SQL Server中一个非常强大的功能,它能够帮助数据库管理员在数据丢失或损坏的情况下,有效地恢复数据。通过定期备份数据库和事务日志,并在需要时按照正确的步骤恢复,可以最大限度地减少数据丢失的风险。需要注意的是,恢复数据是一个需要谨慎操作的过程,建议在执行恢复操作之前,详细了解相关的操作步骤和注意事项,以确保数据的安全和完整。
59 0
|
2月前
|
缓存 监控 Go
[go 面试] 缓存策略与应对数据库压力的良方
[go 面试] 缓存策略与应对数据库压力的良方
下一篇
无影云桌面