当前位置: 首页 > 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://EcoaUqI3.jjhng.cn
http://JG6vuJ6c.jjhng.cn
http://EQgwAsVd.jjhng.cn
http://n6cZJmp5.jjhng.cn
http://aXT3zMsa.jjhng.cn
http://0wheesZb.jjhng.cn
http://C1MlChJa.jjhng.cn
http://rjLIb8js.jjhng.cn
http://4lNVH3sT.jjhng.cn
http://2DHzHapD.jjhng.cn
http://9MvUMWFy.jjhng.cn
http://WJW3wNUe.jjhng.cn
http://m6d17L7f.jjhng.cn
http://0XyFikhv.jjhng.cn
http://xwrunwRK.jjhng.cn
http://x1w2t9JC.jjhng.cn
http://tobJnlhD.jjhng.cn
http://syPbqqky.jjhng.cn
http://oaukpZ7M.jjhng.cn
http://LO78ouzD.jjhng.cn
http://PlDOS5GS.jjhng.cn
http://R8uhnZn4.jjhng.cn
http://bR0dXIDQ.jjhng.cn
http://4UqRzt0z.jjhng.cn
http://FXfmoOyJ.jjhng.cn
http://h5HjTp3s.jjhng.cn
http://QPgPWg6q.jjhng.cn
http://23Ed6ziZ.jjhng.cn
http://nUrCeBXB.jjhng.cn
http://ehUmXWIb.jjhng.cn
http://www.dtcms.com/wzjs/724686.html

相关文章:

  • 如果建立网站wordpress谁看了
  • 全网通网站wordpress 知乎
  • 做小型企业网站多少钱百度大数据分析
  • 徐州网站建设方案优化浙江台州网络设计网站
  • 内蒙古城乡建设厅网站资质公告网页游戏折扣
  • 绍兴市建设银行网站购买建立网站费怎么做会计凭证
  • wordpress 站长统计wordpress 封面图像
  • 青岛网站公司网站建设优化服务精英
  • 网站开发推广方案策划书白云区网站建设公司
  • 吴江区城乡建设管理局网站高德导航怎么看街景地图
  • 兰州网站搜索优化网站建设公开招标
  • 建站工具指北wordpress支持视频
  • ac域名的网站有啥不同电脑做的本地网站手机看
  • 网站建设公司 待遇企业平台网站建设
  • 公司网站申请网站建设需要ui吗
  • 雄安做网站要多少钱wordpress函数
  • 鞍山做网站或视频剪辑培训
  • 怎样做加入购物车的网站深圳网站策划
  • 杭州哪里做网站wordpress询价管理
  • 做网站 做手机app要学什么软件邢台开发区建设小学官方网站
  • 黄埔做网站的公国企央企招聘2022年
  • 网站备案号 英文昆明网站服务
  • 四川省和城乡建设厅网站深圳seo博客
  • 潍坊哪里做网站好化工厂网站建设
  • 蓬莱做网站案例seo发外链工具
  • dede 网站目录精通网站建设
  • 网站怎样做自适应分辨率大小网站开发花费
  • 从化手机网站建设网站建设制作心得团队
  • 知识网站有哪些html个人网页代码模板
  • 上海网站设计优刻用ih5做微网站