Redis(四)事务 multi、exec
有勇气的牛排
681
数据库
2023-03-12 19:57:08
哈喽,大家好,我是有勇气的牛排(全网同名)🐮🐮🐮
有问题的小伙伴欢迎在文末评论,点赞、收藏是对我最大的支持!!!。
文章目录
官方文档:https://redis.io/docs/manual/transactions/
1 前言
1.1 什么是Redis事务
定义:可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地执行,而不会被其他命令插入,不许加塞。
功能:一个队列中,一次性、顺序性、排他性的执行一系列命令。
1.2 Redis事务 & 数据库事务
1、单独的隔离操作 |
Redis的事务仅仅是保证事务的操作会被连续独占的执行,redis命令执行时单线程架构,在执行完事务内所有指令前不可能再去同时执行其他客户端请求的 |
2、没有隔离级别的概念 |
因为事务提交前任务指令都不会被实际执行,也就不存在“事务内的查询要看到事务里的更新,在事务外查询不能看到”这种问题了 |
3、不保证原子性 |
Redis的事务不能保证原子性,也就是不保证所有指令同时成功or同时失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力 |
4、排他性 |
Redis会保证一个事务的命令一次执行,而不会被其他命令插入。 |
2 常用命令
2.1 正常执行
multi
....
exec
2.2 放弃事务
discard
2.3 全体连坐(保证全部成功)
假设其中一个语法出错,则所有命令都失败
multi
set a 1
set b # 错误语法
exec
2.4 冤头债主(失败不影响成功的)
假设有错误命令,成功的不受影响
2.5 watch监控
Redis使用Watch来提供乐观锁定,类似于CAS(Check-and-Set)
就是在exec前,如果原数据被修改,则本此事务失败
# 监控锁
watch <key>
# 放弃监控
unwatch
# 悲观锁(Pessmistic Lock)
每次拿数据的时候都会认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block,直达它拿到锁。
# 乐观锁(Optimistic Lock)
每次拿数据的时候会认为别热不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有咩有去更新这个数据。
乐观锁策略:提交版本必须 > 记录当前版本才能执行更新

<p><font face="楷体,华文行楷,隶书,黑体" color="red" size="4"><strong>哈喽,大家好,我是有勇气的牛排(全网同名)🐮🐮🐮</strong></font></p>
<p><font face="楷体,华文行楷,隶书,黑体" color="blue" size="4"><strong>有问题的小伙伴欢迎在文末评论,点赞、收藏是对我最大的支持!!!。</strong></font></p>
<p><h3>文章目录</h3><ul><ul><li><a href="#1__10">1 前言</a></li><ul><li><a href="#11_Redis_12">1.1 什么是Redis事务</a></li><li><a href="#12_Redis___20">1.2 Redis事务 & 数据库事务</a></li></ul><li><a href="#2__30">2 常用命令</a></li><ul><li><a href="#21__32">2.1 正常执行</a></li><li><a href="#22__40">2.2 放弃事务</a></li><li><a href="#23__46">2.3 全体连坐(保证全部成功)</a></li><li><a href="#24__61">2.4 冤头债主(失败不影响成功的)</a></li><li><a href="#25_watch_65">2.5 watch监控</a></li></ul></ul></ul></p>
<p>官方文档:https://redis.io/docs/manual/transactions/</p>
<h2><a id="1__10"></a>1 前言</h2>
<h3><a id="11_Redis_12"></a>1.1 什么是Redis事务</h3>
<p>定义:可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,<strong>按顺序地执行,而不会被其他命令插入,不许加塞。</strong></p>
<p>功能:一个队列中,一次性、顺序性、排他性的执行一系列命令。</p>
<h3><a id="12_Redis___20"></a>1.2 Redis事务 & 数据库事务</h3>
<table>
<thead>
<tr>
<th>1、单独的隔离操作</th>
<th>Redis的事务仅仅是保证事务的操作会被连续独占的执行,redis命令执行时单线程架构,在执行完事务内所有指令前不可能再去同时执行其他客户端请求的</th>
</tr>
</thead>
<tbody>
<tr>
<td>2、没有隔离级别的概念</td>
<td>因为事务提交前任务指令都不会被实际执行,也就不存在“事务内的查询要看到事务里的更新,在事务外查询不能看到”这种问题了</td>
</tr>
<tr>
<td>3、不保证原子性</td>
<td>Redis的事务不能保证原子性,也就是不保证所有指令同时成功or同时失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力</td>
</tr>
<tr>
<td>4、排他性</td>
<td>Redis会保证一个事务的命令一次执行,而不会被其他命令插入。</td>
</tr>
</tbody>
</table>
<h2><a id="2__30"></a>2 常用命令</h2>
<h3><a id="21__32"></a>2.1 正常执行</h3>
<pre><div class="hljs"><code class="lang-shell">multi
....
exec
</code></div></pre>
<h3><a id="22__40"></a>2.2 放弃事务</h3>
<pre><div class="hljs"><code class="lang-shell">discard
</code></div></pre>
<h3><a id="23__46"></a>2.3 全体连坐(保证全部成功)</h3>
<p>假设其中一个语法出错,则所有命令都失败</p>
<pre><div class="hljs"><code class="lang-shell">multi
set a 1
set b # 错误语法
exec
</code></div></pre>
<h3><a id="24__61"></a>2.4 冤头债主(失败不影响成功的)</h3>
<p>假设有错误命令,成功的不受影响</p>
<h3><a id="25_watch_65"></a>2.5 watch监控</h3>
<p>Redis使用Watch来提供乐观锁定,类似于CAS(Check-and-Set)</p>
<ul>
<li>悲观锁</li>
<li>乐观锁</li>
<li>CAS</li>
</ul>
<p>就是在exec前,如果原数据被修改,则本此事务失败</p>
<pre><div class="hljs"><code class="lang-shell"><span class="hljs-meta"># </span><span class="language-bash">监控锁</span>
watch <key>
<span class="hljs-meta">
# </span><span class="language-bash">放弃监控</span>
unwatch
</code></div></pre>
<pre><div class="hljs"><code class="lang-shell"><span class="hljs-meta"># </span><span class="language-bash">悲观锁(Pessmistic Lock)</span>
每次拿数据的时候都会认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block,直达它拿到锁。
<span class="hljs-meta">
# </span><span class="language-bash">乐观锁(Optimistic Lock)</span>
每次拿数据的时候会认为别热不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有咩有去更新这个数据。
乐观锁策略:提交版本必须 > 记录当前版本才能执行更新
</code></div></pre>
<p><img src="https://static.couragesteak.com/article/f8496345604fab7123e9836ca0ce152b.png" alt="image.png" /></p>
留言