04-事务的四大特征,四种隔离级别,三大读,乐观锁和悲观锁

2023-12-17 11:12

本文主要是介绍04-事务的四大特征,四种隔离级别,三大读,乐观锁和悲观锁,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

事务(transaction)

四个特征ACID

一个业务通常需要多条DML(增删改)语句共同联合起来(同时成功或失败)才能完成,那么事务其实就是这个完整的业务逻辑,是一个最小的工作单元不可再分

  • 只有执行DML语句时才会考虑事务问题, 因为一旦涉及到数据的增、删、改就要考虑安全问题

MySQL默认情况下是支持自动提交事务的,即每执行一条DML语句会自动提交一次,自动提交事务并不符合我们的开发需求

  • 一个业务通常需要多条DML语句同时成功后才能提交事务,为了保证数据的安全我们需要关闭MySQL事务自动提交机制start transaction

事务在执行过程中每一条DML(增删改)的操作都会被记录到InnoDB存储引擎提供的事务性活动的日志文件中,最后根据需求决定是提交还是回滚事务

  • commit,提交事务(标志事务成功结束):,执行之前批量的DML操作然后将数据全部持久化到数据库表中,然后清空事务性活动的日志文件
  • rollback,回滚事务(标志事务失败结束): 将之前所有的DML操作全部撤销(回滚永远都是只能回滚到上一次的提交点),然后清空事务性活动的日志文件
  • 事务只能回滚insert,delete和update语句,不能回滚select,create,drop,alter这些操作因为没有任何意义

事务的四个处理过程

  • 第一步: 开启事务start transaction

  • 第二步: 执行核心业务代码包含批量的DML语句

  • 第三步: 如果核心业务代码处理过程中没有出现异常则提交事务commit

  • 第四步: 如果核心业务代码处理过程中出现异常回滚事务rollback

事务的四个特性原子性,一致性,隔离性,持久性

特性描述
Atomicity(原子性)说明事务是最小的工作单元,整个事务中的所有操作必须作为一个单元即全部完成或全部取消
Consistency(一致性)在同一个事务当中所有操作必须同时成功或失败,保证数据库从一个一致性状态转换到另一个一致性状态
Isolation(隔离性)A事务和B事务操作同一张表的时候,事务之间需要具有一定的隔离性
事务并发就是一个线程一个事务
Durability(持久性)事务一旦提交后该事务对数据库所作的更改将持久地保存在数据库之中,即使数据库发生故障也无法回滚

事务的提交与回滚

-- 使用bjpowernode数据库
mysql> use bjpowernode;
-- 查询dept_bak表中的数据        
mysql> select * from dept_bak;+--------+-------+------+| DEPTNO | DNAME | LOC  |+--------+-------+------+|     10 | abc   | bj   |+--------+-------+------+1 row in set (0.00 sec)
-- 开启事务,关闭事务的自动提交机制
mysql> start transaction;
-- 向dept_bak表中插入数据
mysql> insert into dept_bak values(20,'abc','bj');
-- 提交事务
mysql> commit;
-- 再次查看表中的数据
mysql> select * from dept_bak;+--------+-------+------+| DEPTNO | DNAME | LOC  |+--------+-------+------+|     10 | abc   | bj   ||     20 | abc   | tj   |+--------+-------+------+
-- 回滚事务只能回滚到上一次的提交点
mysql> rollback;
-- 再次查看表中的数据
mysql> select * from dept_bak;+--------+-------+------+| DEPTNO | DNAME | LOC  |+--------+-------+------+|     10 | abc   | bj   ||     20 | abc   | tj   |+--------+-------+------+

事务的隔离级别(三大读)

InnoDB存储引擎实现了四个隔离级别用以控制每个事务所做的修改.并将修改通告至其它并发的事务

名称描述
脏读在事务A中读取到了事务B未提交到数据库的数据,由于事务B可能回滚,所以事务A可能会读取到数据库中不存在的数据
不可重复读(读-读)事务B在事务A多次读取同一数据的过程中对事务A读取的数据做了更新操作并提交,导致事务A每次读取的数据都不一致
幻读(读-写)某一次的读操作得到的结果无法支撑后续的业务操作,多事务并发的情况下一定会存在幻读现象
在可重复读的情况下,事务A想插入一条id=5的记录,此时事务B把这条记录插入了并提交了事务,但是事务A看不到事务B插入的记录,结果就是事务A插入时报错了
隔离级别描述脏读不可重复读幻读加锁读
读未提交(理论级别)(READ_UNCOMMITTED)在一个事务中可以看到其他事务未提交的修改数据,大多数的数据库隔离级别都是二档起步不加锁
读已提交 (Oracle默认级别)
(READ_COMMITTED)
在一个事务中只能看到其他事务已经提交的修改数据,这种隔离级别每次读到的都是真实数据不加锁
可重复读(MySQL默认级别)
(REPEATABLE_READ)
一个事务中多次执行相同的SELECT语句得到的是相同的结果,永远读取的都是自己刚开启事务时的数据,不管其他事务是否提交了修改数据不加锁
序列化(最高隔离级别)
SERIALIZABLE
一个事务与其他事务完全地隔离,每一次读取到的数据都是最真实的,但是所有事务只能排队执行,不支持并发所以效率最低加锁

设置服务的隔离级别

设置MySQL服务默认的事务隔离级别: 在my.ini配置文件中配置[mysqld]选项的transaction-isolation属性

#该选项值可以是READ-UNCOMMITTED , READ-COMMITTED , REPEATABLE-READ , SERIALIZABLE
[mysqld]
#设置隔离级别,如果没有设置默认是REPEATABLE-READ
transaction-isolation00 = READ-COMMITTED

动态设置MySQL服务的隔离级别:SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL <isolation-level>,设置完后需退出MySQL服务重新进入

  • isolation-level(隔离级别): 隔离级别可以是READ UNCOMMITTED,READ COMMITTED,REPEATABLE READ,SERIALIZABLE

  • 全局级(GLOBAL): 设置的隔离级别对所有的会话有效

  • 会话级(SESSION): 默认设置的隔离级别只对当前的会话有效

-- 设置隔离级别为READ COMMITTED ,默认只对当前的会话有效
mysql> SET TRANSACTION ISOLATION LEVEL READ COMMITTED-- 设置会话级隔离级别为READ COMMITTED 
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED-- 设置全局级隔离级别为READ COMMITTED :
mysql> SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED

查看MySQL服务当前的隔离级别: 服务器变量tx_isolation默认保存着当前的会话隔离级别

-- 查看当前隔离级别,默认是会话级别
mysql> SELECT @@tx_isolation;
-- 查看当前会话的隔离级别
mysql> SELECT @@session.tx_isolation;
-- 查看当前全局的隔离级别
mysql> SELECT @@global.tx_isolation;

验证四种隔离界别

验证read uncommited读未提交

事务A事务B
s1>use bjpowernode;s2>set global transaction isolation level read uncommitted;
s1>create table tx ( id int(11),num int (10));s2>use bjpowernode;
s1>start transaction;s2>start transaction;
s2>select * from tx;(空表)
s1>insert into tx values (1,10);事务A还没有提交
s2>select * from tx;事务B读取到了事务A未提交的数据
s1>rollback;
s2>select * from tx;

验证read commited读已提交

事务A事务B
s1>use bjpowernodes2> set global transaction isolation level read committed;
s1>start transaction;s2>use bjpowernode;
s2>start transaction;
s2>select * from tx;(空表)
s1>insert into tx values (1,10);
s2>select * from tx;由于事务A没有提交数据,事务B的读取的还是空表
s1>commit;事务A提交了数据
s2>select * from tx;事务B读取到了事务A已提交的数据

验证repeatable read可重复读

事务A事务B
s1>use bjpowernodes2>set global transaction isolation level repeatable read;
s1>start transaction;s2>use bjpowernode;
s2>start transaction;
s2>select * from tx;事务B开启时的数据
s1>insert into tx values (1,10);
s1>commit;事务A提交了数据
s2>select * from tx;即使事务A提交了数据,事务B读取的还是自己开启事务时的数据

验证serializable序列化

事务A事务B
s1>use bjpowernode;s2>set global transaction isolation level serializable;
s1>start transaction;s2>use bjpowernode;
select * from tx;s2>start transaction;
s1>insert into tx values (1,10);事务A在操作tx表时,只要当前事务不结束,其他事务就不能访问tx表
s2>select * from tx;事务B不能访问tx表

乐观锁和悲观锁

乐观锁: 支持事务并发,只不过需要设置给数据库中的表设置一个版本号字段

悲观锁(行级锁): 事务必须排队执行

  • 事务A在执行select语句时加上for update,表示将查询到的所有记录整行锁住,此时只要事务A不提交事务,其他事务就无法对这些记录进行修改操作

第一步: 开启一个事务A专门进行查询,并且使用行级锁锁住查询到的记录

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
// 使用工具类获取连接对象
conn = DBUtil.getConnection();
// 将数据库的自动提交功能改为手动提交,即开启数据库事务的功能
conn.setAutoCommit(false);
// 获取预编译的数据库操作对象
String sql = "select ename from emp where job = ? for update";
ps = conn.prepareStatement(sql);
ps.setString(1, "MANAGER");
rs = ps.executeQuery();
while(rs.next()){System.out.println(rs.getString("ename"));
}
// 提交事务
conn.commit();
// 关闭资源
DBUtil.close(conn,ps,rs)

第二步: 开启一个事务B修改锁定的记录,此时发现只要事务A不结束,事务B的修改操作就无法执行

Connection conn = null;
PreparedStatement ps = null;
// 使用工具类获取连接
conn = DBUtil.getConnection();
// 关闭数据库的自动提交功能改为手动提交, 即开启数据库事务的功能
conn.setAutoCommit(false);
// 获取预编译的数据库操作对象
String sql = "update emp set sal = sal * 1.1 where job = ? ";
ps = conn.prepareStatement(sql);
ps.setString(1, "MANAGER");
int count = ps.executeUpdate();
System.out.println(rs.getString(count));
// 提交事务
conn.commit();
// 关闭资源
DBUtil.close(conn,ps,null)

这篇关于04-事务的四大特征,四种隔离级别,三大读,乐观锁和悲观锁的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/504171

相关文章

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

取得 Git 仓库 —— Git 学习笔记 04

取得 Git 仓库 —— Git 学习笔记 04 我认为, Git 的学习分为两大块:一是工作区、索引、本地版本库之间的交互;二是本地版本库和远程版本库之间的交互。第一块是基础,第二块是难点。 下面,我们就围绕着第一部分内容来学习,先不考虑远程仓库,只考虑本地仓库。 怎样取得项目的 Git 仓库? 有两种取得 Git 项目仓库的方法。第一种是在本地创建一个新的仓库,第二种是把其他地方的某个

MySql 事务练习

事务(transaction) -- 事务 transaction-- 事务是一组操作的集合,是一个不可分割的工作单位,事务会将所有的操作作为一个整体一起向系统提交或撤销请求-- 事务的操作要么同时成功,要么同时失败-- MySql的事务默认是自动提交的,当执行一个DML语句,MySql会立即自动隐式提交事务-- 常见案例:银行转账-- 逻辑:A给B转账1000:1.查询

线程的四种操作

所属专栏:Java学习        1. 线程的开启 start和run的区别: run:描述了线程要执行的任务,也可以称为线程的入口 start:调用系统函数,真正的在系统内核中创建线程(创建PCB,加入到链表中),此处的start会根据不同的系统,分别调用不同的api,创建好之后的线程,再单独去执行run(所以说,start的本质是调用系统api,系统的api

OmniGlue论文详解(特征匹配)

OmniGlue论文详解(特征匹配) 摘要1. 引言2. 相关工作2.1. 广义局部特征匹配2.2. 稀疏可学习匹配2.3. 半稠密可学习匹配2.4. 与其他图像表示匹配 3. OmniGlue3.1. 模型概述3.2. OmniGlue 细节3.2.1. 特征提取3.2.2. 利用DINOv2构建图形。3.2.3. 信息传播与新的指导3.2.4. 匹配层和损失函数3.2.5. 与Super

如何掌握面向对象编程的四大特性、Lambda 表达式及 I/O 流:全面指南

这里写目录标题 OOP语言的四大特性lambda输入/输出流(I/O流) OOP语言的四大特性 面向对象编程(OOP)是一种编程范式,它通过使用“对象”来组织代码。OOP 的四大特性是封装、继承、多态和抽象。这些特性帮助程序员更好地管理复杂的代码,使程序更易于理解和维护。 类-》实体的抽象类型 实体(属性,行为) -》 ADT(abstract data type) 属性-》成

Lua 脚本在 Redis 中执行时的原子性以及与redis的事务的区别

在 Redis 中,Lua 脚本具有原子性是因为 Redis 保证在执行脚本时,脚本中的所有操作都会被当作一个不可分割的整体。具体来说,Redis 使用单线程的执行模型来处理命令,因此当 Lua 脚本在 Redis 中执行时,不会有其他命令打断脚本的执行过程。脚本中的所有操作都将连续执行,直到脚本执行完成后,Redis 才会继续处理其他客户端的请求。 Lua 脚本在 Redis 中原子性的原因

浙大数据结构:04-树7 二叉搜索树的操作集

这道题答案都在PPT上,所以先学会再写的话并不难。 1、BinTree Insert( BinTree BST, ElementType X ) 递归实现,小就进左子树,大就进右子树。 为空就新建结点插入。 BinTree Insert( BinTree BST, ElementType X ){if(!BST){BST=(BinTree)malloc(sizeof(struct TNo

《计算机视觉工程师养成计划》 ·数字图像处理·数字图像处理特征·概述~

1 定义         从哲学角度看:特征是从事物当中抽象出来用于区别其他类别事物的属性集合,图像特征则是从图像中抽取出来用于区别其他类别图像的属性集合。         从获取方式看:图像特征是通过对图像进行测量或借助算法计算得到的一组表达特性集合的向量。 2 认识         有些特征是视觉直观感受到的自然特征,例如亮度、边缘轮廓、纹理、色彩等。         有些特征需要通

读软件设计的要素04概念的关系

1. 概念的关系 1.1. 概念是独立的,彼此间无须相互依赖 1.1.1. 一个概念是应该独立地被理解、设计和实现的 1.1.2. 独立性是概念的简单性和可重用性的关键 1.2. 软件存在依赖性 1.2.1. 不是说一个概念需要依赖另一个概念才能正确运行 1.2.2. 只有当一个概念存在时,包含另一个概念才有意义 1.3. 概念依赖关系图简要概括了软件的概念和概念存在的理