当前位置: 首页 > wzjs >正文

免费注册网站互联网平台营销

免费注册网站,互联网平台营销,汉中做网站,在线作图网悲观锁和乐观锁是两种常见的并发控制方式,它们在处理并发数据访问时的策略和实现方式有很大的不同。下面是这两者的主要区别: 1. 锁的策略 悲观锁(Pessimistic Locking): 假设并发冲突频繁发生,因此在操作…

悲观锁和乐观锁是两种常见的并发控制方式,它们在处理并发数据访问时的策略和实现方式有很大的不同。下面是这两者的主要区别:

1. 锁的策略

悲观锁(Pessimistic Locking):

假设并发冲突频繁发生,因此在操作数据之前就会加锁,确保其他事务无法同时操作这条数据,避免数据的并发修改。只有获得锁的事务才能对数据进行修改,其他事务会被阻塞,直到当前事务完成。

  • 特点:乐观地认为数据可能会被同时修改,因此采取悲观的做法,强制加锁。
  • 实现方式:通过 SELECT FOR UPDATE 或数据库的锁机制(例如行锁、表锁)来实现。
  • 适用场景:适用于高并发情况下需要保证数据一致性的业务场景,例如资金转账、库存扣减等。

乐观锁(Optimistic Locking):

假设并发冲突较少,事务并不会立刻加锁,而是在更新时验证数据是否被其他事务修改。如果数据在事务操作期间没有被其他事务修改(通常通过版本号等机制检查),就可以提交更新;如果数据已经被其他事务修改,则会回滚或抛出异常。

  • 特点:乐观地认为数据不会被并发修改,因此不加锁,只在更新时进行冲突检查。
  • 实现方式:通常通过在数据表中添加 version 字段或时间戳字段,每次更新时检查版本号是否一致来实现。
  • 适用场景:适合读多写少的业务场景。适用于并发冲突较少,且更新操作不频繁的场景,例如普通的查询和更新操作。

2. 锁的粒度

悲观锁:
会对数据进行实际的加锁,其他事务在该数据的锁释放之前无法访问或修改数据。锁的粒度通常为行锁或表锁,具体取决于数据库的实现。

乐观锁:
不会对数据加锁,只是在数据修改时检查版本号或时间戳等信息,以判断数据是否被其他事务修改过。它的粒度通常为数据记录的版本字段

3. 性能与开销

悲观锁:
由于加锁机制,它的性能开销较大。多个事务竞争同一数据时,其他事务需要等待锁释放,可能导致性能瓶颈,尤其在高并发的情况下。

乐观锁:
由于没有加锁,它的性能较高,适合读取操作多、写入操作少的场景。它的开销主要在于更新时的版本检查,性能损耗较低。

4. 适用场景

悲观锁:
适用于数据竞争较为激烈的场景,例如银行转账、库存更新等高并发操作。
适用于对数据一致性要求极高的业务场景,需要强制保证同一时间只有一个事务能修改数据。

乐观锁:
适用于数据竞争较少的场景,例如用户资料更新、普通的库存查询等。
适用于不频繁更新的场景,可以减少数据库的锁竞争,提高系统的吞吐量。

5. 事务阻塞

悲观锁:
由于加锁,其他事务在等待锁释放期间会被阻塞,可能会引起性能下降或死锁。

乐观锁:
不会导致阻塞,多个事务可以同时读取数据,只有在提交时检查数据是否被修改。若数据被修改,则需要回滚或重新尝试更新,但不会影响其他事务的执行。

6. 死锁风险

悲观锁:
在并发高的情况下,悲观锁可能导致死锁(特别是当事务顺序不一致时),因为多个事务可能会相互等待对方释放锁。

乐观锁:
乐观锁不会产生死锁,因为它没有显式的锁操作。它依赖版本号来解决并发问题,即使并发冲突发生,也只是简单的版本检查或回滚。

7. 在Spring Boot中悲观锁的实现

使用 MyBatis-Plus 实现悲观锁,实际上就是通过 SQL 查询语句 来加锁。在 MyBatis 中,可以通过 FOR UPDATE 来实现悲观锁。

1.修改数据库查询,使用悲观锁:

使用 FOR UPDATE 来锁定查询到的行。你可以在 Mapper 中自定义 SQL 查询,指定 FOR UPDATE

假设你有一个 gift 表,表结构如下:

CREATE TABLE gift (id BIGINT PRIMARY KEY,name VARCHAR(255),quantity INT
);

在 Mapper 接口中,定义一个查询方法,使用 FOR UPDATE

@Mapper
public interface GiftMapper extends BaseMapper<Gift> {@Select("SELECT * FROM gift WHERE id = #{id} FOR UPDATE")Gift selectForUpdate(Long id);
}

2.服务层调用悲观锁:

在服务层使用 @Transactional 注解,确保事务的原子性。

@Service
public class GiftService {@Autowiredprivate GiftMapper giftMapper;@Transactionalpublic boolean redeemGift(Long giftId) {Gift gift = giftMapper.selectForUpdate(giftId);if (gift == null) {return false;}// 检查库存if (gift.getQuantity() > 0) {gift.setQuantity(gift.getQuantity() - 1);giftMapper.updateById(gift);return true;} else {return false;}}
}

在上述代码中,selectForUpdate 查询会加锁,确保只有一个事务可以操作该记录。如果其他事务尝试访问该记录,它们会被阻塞,直到当前事务完成。

3.数据库配置:

默认情况下,PostgreSQL 的隔离级别是 READ COMMITTED,它支持 FOR UPDATE 锁。如果你需要更高的隔离级别,可以配置事务隔离级别为 SERIALIZABLE,但是对于大多数场景,READ COMMITTED 就足够了。

可以在 application.properties 文件中配置事务隔离级别:

spring.datasource.hikari.transaction-isolation=TRANSACTION_READ_COMMITTED

8. 在Spring Boot中乐观锁的实现

<!--mybatis 官方-->
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version>
</dependency><!--mybatis plus 非官方-->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version>
</dependency>

乐观锁通常通过版本号机制来实现。每次更新数据时,会验证数据是否被其他事务修改过。如果数据被修改,则抛出 OptimisticLockException 异常,提示并发冲突。

1.在config包中添加乐观锁配置类:

package com.ckm.ball.config;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@MapperScan("com.ckm.ball.mapper") // 扫描你的 Mapper 包
public class MyBatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {// 注册乐观锁插件MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;}
}

2.在实体类中添加版本字段:

在实体类中添加 version 字段,并使用 MyBatis-Plus 提供的 @Version 注解来标识该字段为版本号字段。

import com.baomidou.mybatisplus.annotation.*;@TableName("gift")
public class Gift {@TableIdprivate Long id;private String name;private Integer quantity;@Versionprivate Long version;  // 版本字段// getters and setters
}

在这个例子中,version 字段会随着每次更新而自动递增。

3.更新时使用乐观锁:

MyBatis-Plus 会自动处理乐观锁的更新。你只需在更新时,确保在实体类中包含 @Version 注解的字段。

例如,在服务层进行更新操作时,MyBatis-Plus 会自动比较版本号,确保数据没有被其他事务修改。

@Service
public class GiftService {@Autowiredprivate GiftMapper giftMapper;@Transactionalpublic boolean redeemGift(Long giftId) {Gift gift = giftMapper.selectById(giftId);if (gift == null) {return false;}// 检查库存if (gift.getQuantity() > 0) {gift.setQuantity(gift.getQuantity() - 1);// 更新时会自动检查版本号int rows = giftMapper.updateById(gift);if (rows == 0) {// 如果更新失败,说明版本号不匹配,表示并发冲突return false;}//在这里处理里的其他逻辑//如扣除相应积分,存储兑换记录等return true;} else {return false;}}
}

在更新时,MyBatis-Plus 会自动检查 version 字段。如果数据的版本号与当前数据库中的版本号不一致,则更新失败,返回 0,表示发生了并发冲突。

4.配置乐观锁:

如果使用 MyBatis-Plus,乐观锁只需要在实体类中标记 @Version 注解,不需要其他特殊配置。

总结

  • 悲观锁:通过 FOR UPDATE 锁定查询的行,适用于高并发的情况下,确保同一时刻只有一个事务修改数据。你可以通过 MyBatis 的@Select 注解配合 FOR UPDATE 来实现。
  • 乐观锁:通过版本号机制,确保数据在更新时没有被其他事务修改。MyBatis-Plus 支持通过 @Version 注解来实现乐观锁。

文章转载自:

http://oxD2QM1J.bfycr.cn
http://MvXsZZ8c.bfycr.cn
http://7HJYuXOP.bfycr.cn
http://shEHcmbP.bfycr.cn
http://3IkQaTuy.bfycr.cn
http://kUgQ4UDU.bfycr.cn
http://b9NjjqgY.bfycr.cn
http://06JjGDdj.bfycr.cn
http://xPNCoKy4.bfycr.cn
http://qnTHVvyX.bfycr.cn
http://eigNkLRp.bfycr.cn
http://Wt0FRnqC.bfycr.cn
http://bRJLMpRe.bfycr.cn
http://yI8VIk41.bfycr.cn
http://a5iRpnKr.bfycr.cn
http://B0Lifdq0.bfycr.cn
http://oVqERgAL.bfycr.cn
http://dLtxFaI6.bfycr.cn
http://fo9S37Uf.bfycr.cn
http://FANrwD9N.bfycr.cn
http://c8RMQ4Zg.bfycr.cn
http://rxRUPGJb.bfycr.cn
http://KFwkkx0L.bfycr.cn
http://Vb2yWfPV.bfycr.cn
http://Uu4vHxw4.bfycr.cn
http://Ywxq2Fzo.bfycr.cn
http://TuNV9mLi.bfycr.cn
http://euFCbqNP.bfycr.cn
http://tYOfYAvw.bfycr.cn
http://ViQfQT3m.bfycr.cn
http://www.dtcms.com/wzjs/737356.html

相关文章:

  • 南安梅山建设银行网站wordpress打赏可见插件
  • 嘉兴门户网站包头市住房与城乡建设部网站
  • 济南网站建设cnwenhui网站设计与网页设计的区别
  • 网站开发容易找工作吗起个娱乐网站名字
  • 爱是做的电影网站wordpress建站发文教程
  • 如何用ps来做网站设计珠海微网站建设
  • 商丘网站建设价格网页与网站的区别与联系
  • 17我们一起做网站网站的建设与维护工资
  • 泊头网站制作案例做网站的公司多少钱
  • 网站设计收费郑州哪里有做网站的
  • 免费一站式网站建设宁波找网站建设企业
  • 做购物网站费用中国建筑业发展现状
  • 网站建设费能入长期待摊吗网站推广的主要方法有哪些
  • 酷站素材专门做代理的网站
  • 国外的服务器做的网站在国外能打开在国内打不开是什么原因怎么做免费个人网站
  • 网站内部建设和程序wordpress 插件调用文章
  • 视频网站 外链怎么自己做网站框架
  • 网站关键词设置几个wordpress生成微信分享图片
  • flash网站源文件旅行社营业网点可以做网站吗
  • 星河网站建设电子商务网站的网络营销策略分析
  • html网站怎么做几个网页WordPress维护模式退出
  • 做视频解析网站违法不自适应网站推广
  • 郑州网站建设炉石千万不要去做房地产销售
  • 网站大屏轮播图效果怎么做的wordpress注册页面插件
  • 电信备案网站打不开百度智能小程序是什么
  • 建设需要什么系统网站网站建设职员
  • 视频解析网站动漫网站在线免费观看
  • 杭州网站建设专家运城市住房与城乡建设厅网站
  • 商场设计网站东莞网站开发技术公司
  • 个人网站毕业设计论文4399在线观看免费高清1080