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

网站建设解决方案有哪些成都建设网站多少钱

网站建设解决方案有哪些,成都建设网站多少钱,建设网站八大员成绩查询,番禺网站建设wwiw悲观锁和乐观锁是两种常见的并发控制方式,它们在处理并发数据访问时的策略和实现方式有很大的不同。下面是这两者的主要区别: 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://www.dtcms.com/wzjs/808530.html

相关文章:

  • 注册个人网站要钱吗杭州定制网站开发
  • 网站建设填空题茂名手机网站建设公司名录
  • 网站建设需求信息做外贸找工厂货源网站
  • 网站外链隐形框架是什么重庆建网站价格表
  • 使用wordpress搭建网站网站建设与推广推荐
  • 做外贸国外网站网站设计建设公司排行
  • 精品课程网站开发平台seo案例模板
  • 微网站建设及微信推广方案ppt灰色关键词排名收录
  • 网站建设伍金手指下拉7软件工程师40岁后的出路
  • 有专业做外贸的网站吗工作室名字创意好听
  • 有哪些做普洱茶网站的高中作文网官网
  • 速推网网站如何进行代码优化
  • 铜仁市建设局网站wordpress改造熊掌号
  • 营销网站模板html短视频素材网
  • 建设环评备案登记网站做鱫视频网站
  • 在哪个网站找水利工地做手机网站底部导航
  • 网站效果图设计方案网站建设钱
  • 网站开发毕设题目开发网站中心
  • 宁波哪里有做网站的洛阳网站建设睿翼网络入驻洛阳
  • 李宁网站建设的可行性企业微信一年的费用要多少
  • wordpress 失眠先生辽宁好的百度seo公司
  • 深圳市企业网站seo做中英文网站要注意什么
  • 做网站需要用到的软件天津市做企业标准网站
  • 菜鸟怎样做自己的网站wordpress教程app
  • 怎么申请网站域名赚钱淘宝客怎样做网站
  • 借鉴网网站企业网站管理系统 php
  • 网站设计答辩ppt广告型网站建设
  • 台州seo网站排名view主题WordPress
  • 网上购物网站建设需求石家庄站内换乘示意图
  • 工业做网站小程序直播系统开发