长春建设信息网站,六安城市网电话是多少,wordpress留言板页面,go 是做网站的吗前言关系数据库中的事务#xff0c;小伙伴们应该是不陌生了#xff0c;不管是在开发还是在面试过程中#xff0c;总有两个问题逃不掉#xff1a;•说说事务的特性#xff1b;•事务隔离级别是怎么一回事#xff1f;事务处理不好#xff0c;数据就可能不准确#xff0c;… 前言关系数据库中的事务小伙伴们应该是不陌生了不管是在开发还是在面试过程中总有两个问题逃不掉•说说事务的特性•事务隔离级别是怎么一回事事务处理不好数据就可能不准确最终就会导致业务出问题借此机会简单回顾一下事务特性及其隔离级别就当是复习了事务特性(ACID)•原子性Atomicity指事务内所有操作要么一起执行成功要么都一起失败(或者说是回滚)如事务经典转账案例A给B转账A把钱扣了但B没有收到可见这种错误是不能接受的最终会回滚这也是原子性的重要性。•一致性Consistency指事务执行前后的状态一致如事务经典转账案例A给B互相转账不管怎么转最终两者钱的总和还是不变•持久性Durability指事务一旦提交数据就已经永久保存了不能再回滚•隔离性Isolation指多个并发事务之间的操作互不干扰但是事务的并发可能会导致数据脏读、不可重复读、幻读问题根据业务情况采用事务隔离级别进行对应数据读问题处理。事务隔离级别•读未提交(Read uncommitted)指一个事务读取到其他未提交事务的数据。可能导致数据脏读。转账案例A正在给B转账本来转的1000A多输入了个0变成10000但此事务还未提交但此时B查询到转入的是10000但A取消事务回滚之后B又查询不到转入的数据。这种情况就是脏读•读已提交(Read committed)指一个事务只能读取到其他事务已提交的数据从而解决了脏读的问题。但可能导致数据不可重复读转账案例A要给B转账1000A先查看了一下余额有1000然后开始给B转钱但此时A家里电费通过开启的自动缴费功能自动从A账户扣除200缴纳电费并提交当A转账准备提交再次确认余额时钱少了200。这样就导致同一个事务中多次查询的结果不一致这种情况就是不可重复读•可重复读(Repeatable read)指事务只要一开启就不允许其他事务进行修改操作从而解决了不可重复读问题。但可能导致数据幻读转账案例A经常给B转账到年底了需要查账然后开启了一个事务进行查询统计刚开始查询只是10条转账记录正准备统计时因为紧急情况A需要给B转一笔钱应急从而新增了一条新记录并提交而查账事务正在统计中最后发现转账额和看到的10条转账记录不匹配。这种情况就是幻读•序列化(Serializable )指事务之间只能串行话执行就像队列一样排队进行这样就解决了幻读的问题但是这种级别的并发性能不高非特殊需求这种级别一般不用。正文转入正题结合关系型数据库的事务来看看Redis中事务有什么不同Redis事务是指将多条命令加入队列一次批量执行多条命令每条命令会按顺序执行事务执行过程中不会受客户端传入的命令请求影响。Redis事务的相关命令如下•MULTI标识一个事务的开启即开启事务•EXEC执行事务中的所有命令即提交•DISCARD放弃事务和回滚不一样Redis事务不支持回滚。•WATCH监视Key改变用于实现乐观锁。如果监视的Key的值改变事务最终会执行失败。•UNWATCH放弃监视。Redis事务和关系型数据库的事务不太一样它不保证原子性也没有隔离级别的概念。来结合命令演示实战说明一切没有隔离级别image-20201112153132140如上图所示当事务开启时事务期间的命令并没有执行而是加入队列只有执行EXEC命令时事务中的命令才会按照顺序一一执行从而事务间就不会导致数据脏读、不可重复读、幻读的问题因此就没有隔离级别。不保证原子性image-20201112154524168如上图所示在通过EXEC执行事务时其中命令执行失败不会影响到其他命令的执行并没有保证同时成功和同时失败的原子操作尽管这样Redis事务中也没有提供回滚的支持官方提供了两个理由image-20201112160255544大概的意思就是•使用Redis命令语法错误或是将命令运用在错误的数据类型键上(如对字符串进行加减乘除等)从而导致业务数据有问题这种情况认为是编程导致的错误应该在开发过程中解决避免在生产环境中发生•由于不用支持回滚功能Redis内部简单化而且还比较快在事务命令入队过程中发现相关命令逻辑使用错误可以进行放弃该事务如果使用错误的Redis命令且没有放弃事务最终也会导致事务整体执行失败这也算是为原子性扳回一局如下放弃事务image-20201112223050653命令语法错误导致事务执行失败image-20201112223821761使用WATCH实现乐观锁说到乐观锁就和悲观锁一起简单说说对其的理解乐观锁就是非常乐观做什么事都往好处想对于数据库操作就认为每次操作数据的时候都认为别的操作不会修改所以不会加锁而是通过一个类似于版本的字段来标识该数据是否修改过在执行本次操作前先判断是否修改过如果修改过就放弃本次操作重新再来悲观锁就是非常悲观做什么事都觉得不好对于数据库操作每次操作数据数据都会认为别的操作会修改当前数据所以都要对其进行加锁类似于表锁和行锁。WATCH通过监视指定Redis Key如果没有改变就执行成功如果发现对应值发生改变事务就会执行失败如下图image-20201112232612965那会一直监视指定的Key吗答案当然是不会的以下三种方式可以取消监视•事务执行之后不管是否执行成功还好是失败都会取消对应的监视•当监视的客户端断开连接时也会取消监视•可以手动UNWATCH取消所有Key的监视Redis事务优缺点优点•一次性按顺序执行多个Redis命令不受其他客户端命令请求影响•事务中的命令要么都执行(命令间执行失败互相不影响)要么都不执行(比如中间有命令语法错误)缺点•事务执行时不能保证原子性•命令入队每次都需要和服务器进行交互增加带宽注意•当事务中命令语法使用错误时最终会导致事务执行不成功即事务内所有命令都不执行•当事务中命令知识逻辑错误就比如给字符串做加减乘除操作时只能在执行过程中发现错误这种事务执行中失败的命令不影响其他命令的执行。总结对于Redis事务其实用的不是很多大部分喜欢使用Lua脚本进行批量命令的执行同时还能保证命令执行的原子性。那为什么要说Redis事务呢在之前计划写这篇文章的时候和一些朋友简单沟通过大家的确用的不多基本上都是用Lua脚本但面试会时不时遇到过Redis事务的问题最常见的是Redis中的事务和关系型数据库中的事务有什么区别这是从面试角度出发有这篇文章其实Redis 2.6版本之前还不支持Lua脚本时Redis事务对于批量按序执行命令的场景也是很用的就拿当下来说如果一些业务需批量按序执行命令的同样可以使用并非一定要Lua脚本。这是从使用角度来说最后从学习角度来说既然学Redis就应该尽可能的了解的多一点。下一篇说说持久化。一个被程序搞丑的帅小伙关注Code综艺圈跟我一起学~