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 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> No.2.6_5 Redis事务 -> 正文阅读

[大数据]No.2.6_5 Redis事务

相关链接


1. 事务

Redis单条命令是保证原子性的,但是事务不保证原子性。一个事务中所有的命令都会被序列化(事务执行的过程中,会按照顺序执行)

事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。
?
原子性(atomicity):一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。
一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
隔离性(isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

Redis事务的三个特性:一次性、顺序性、排他性。
?
一次性:在一个队列里一次性执行。
顺序性:按照顺序执行。
排他性:执行事务过程中不允许被干扰。
?
Redis事务是没有隔离级别的概念,所有命令在事务中,并没有直接被执行,只有发起执行命令的时候才会执行。

------ 队列 set set set 执行 ------

Redis事务
??● 开启事务( Multi )
??● 命令入队( 其他命令… )
??● 执行事务( exec ) / 放弃事务 ( discard )


1.1 执行事务

# multi # 开启事务
# exec # 执行事务

127.0.0.1:6379> flushdb	# 清空当前数据库
OK
127.0.0.1:6379> multi	# 开启事务
OK
127.0.0.1:6379(TX)> set k1 v1 # 命令入队
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> get k2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> exec	# 执行事务(执行后事务就关闭了)
1) OK
2) OK
3) "v2"
4) OK

1.2 放弃事务

# multi # 开启事务
# discard # 放弃事务

127.0.0.1:6379> flushdb	# 清空当前数据库
OK
127.0.0.1:6379> multi	# 开启事务
OK
127.0.0.1:6379(TX)> set k1 v1 # 命令入队
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> discard # 放弃事务(入队的命令不会执行)
OK
127.0.0.1:6379> get k1	# set k1 v1没有执行 所以取不到
(nil)

2. 事务异常

2.1 编译型异常

??编译型异常(命令有误,不能通过编译),事务中所有的命令都不会执行。

127.0.0.1:6379> flushdb	# 清空数据库
OK
127.0.0.1:6379> multi	# 开启事务
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> zet k3	#错误命令
(error) ERR unknown command `zet`, with args beginning with: `k3`,	# 未通过编译
127.0.0.1:6379(TX)> exec											# 开启事务失败
(error) EXECABORT Transaction discarded because of previous errors.	
127.0.0.1:6379> get k1												# 事务中的命令都不会执行
(nil)

2.2 运行时异常

??运行时异常(例如1/0),如果事务队列中存在语法性,那么执行命令的时候,其他命令是可以正常执行的,错误命令抛出异常。

127.0.0.1:6379> flushdb	# 清空当前数据库
OK
127.0.0.1:6379> multi	# 开启事务
OK
127.0.0.1:6379(TX)> geoadd china:city 39.91667 116.41667 beijing	# geo添加地理空间,这里超出了经纬度限制范围
QUEUED																# 语法没有错误,通过编译
127.0.0.1:6379(TX)> set k1 v1			
QUEUED
127.0.0.1:6379(TX)> exec											# 执行事务
1) (error) ERR invalid longitude,latitude pair 39.916670,116.416670	# 运行时出现异常,超出经纬度范围
2) OK
127.0.0.1:6379> get k1												# 队列中其他命令是可以正常执行的
"v1"

3. 监控实现乐观锁

Redis监控:watch、unwatch

mysql悲观锁:很悲观,认为任何时候都会出问题,无论做什么都要加锁。
mysql乐观锁:很乐观,认为什么时候都不会出问题,所以不会上锁。
???1) 获取version
???2) 更新数据的时候判断一下version字段是否和之前记录的一致(是否有人修改过这个数据)

3.1 监控 正常执行


127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set in 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch in		# 开启监控
OK
127.0.0.1:6379> multi			# 开启事务
OK
127.0.0.1:6379(TX)> incrby in -20	#  in += -20
QUEUED
127.0.0.1:6379(TX)> incrby out 20	# out += 20
QUEUED
127.0.0.1:6379(TX)> exec		# 执行事务
1) (integer) 80
2) (integer) 20

3.2 监控 执行失败

############################# 线程一 ##################################

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> watch money		# 开启监控
OK
...
############################# 线程二 ##################################

127.0.0.1:6379> get money
"0"
127.0.0.1:6379> set money 1000	# 修改了线程一事务中的值
OK
127.0.0.1:6379> set money 0	# 只要有修改动作,就算再改回0,线程一的事务也会失败
OK
############################# 线程一 ##################################

...
127.0.0.1:6379> multi			# 开启事务
OK
127.0.0.1:6379(TX)> incrby money 20	#  money += 20
QUEUED
127.0.0.1:6379(TX)> exec		# 执行事务
(nil)							# (nil)表示修改失败

# 失败后再次执行事务,对money修改,此时监控仍未关闭,应该执行失败(但Redis6.2.6版本会自动关闭事务)
127.0.0.1:6379> multi			# 开启事务 
OK
127.0.0.1:6379(TX)> incrby money 20	#  money += 20
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 120				# 执行成功(在一些旧的redis版本可能会执行失败,需要先unwatch解除监控,再开启监控)

3.2 监控 事务成功后,监视自动关闭

############################# 线程一 ##################################
# 经测试,Redis6.2.6版本在事务执行完毕后会自动关闭监控
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> watch money		# 开启监控
OK
127.0.0.1:6379> multi			# 开启事务
OK
127.0.0.1:6379(TX)> incrby money 20	
QUEUED
127.0.0.1:6379(TX)> exec		# 执行事务(这里测试的是Redis6.2.6版本,
								# 会把监控自动关掉,相当于执行了unwatch,其他版本未测试)
1) (integer) 120				
############################# 线程二 ##################################

127.0.0.1:6379> get money
"120"
127.0.0.1:6379> set money 1000	# 修改了线程一事务中的值
OK
127.0.0.1:6379> set money 120	# 只要有修改动作,就算再改回0,线程一的事务也会失败
OK
############################# 线程一 ##################################
...
127.0.0.1:6379> multi			# 开启事务
OK
127.0.0.1:6379(TX)> incrby money 20	
QUEUED
127.0.0.1:6379(TX)> exec		# 执行事务成功(最开始watch的数值是120,线程二有修改动作,但仍然成功,说明监控被关闭了)
1) (integer) 140	

22/03/07

M

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:34:18  更:2022-03-08 22:35:28 
 
开发: 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 9:11:41-

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