wordpress模版使用,网站同时做竞价和优化可以吗,wordpress 联盟插件怎么用,基础做网站的小结悲观锁、乐观锁、mybatis-plus实现乐观锁 转载自#xff1a;www.javaman.cn 1、悲观锁、乐观锁
乐观锁和悲观锁是两种用于处理并发操作的数据锁定策略。它们在处理多个事务尝试同时访问和修改同一数据时的方法有所不同。
悲观锁 (Pessimistic Locking)#xff1a; 概念www.javaman.cn 1、悲观锁、乐观锁
乐观锁和悲观锁是两种用于处理并发操作的数据锁定策略。它们在处理多个事务尝试同时访问和修改同一数据时的方法有所不同。
悲观锁 (Pessimistic Locking) 概念悲观锁是一种基于悲观态度的数据并发控制机制。它总是假设最坏的情况即认为其他事务会尝试修改数据因此在读取数据时就会加锁以确保在此期间其他事务不能修改数据。工作原理当一个事务想要读取或修改数据时它会先请求锁。如果锁已经被其他事务持有则当前事务会被阻塞直到锁被释放。这确保了每次只有一个事务可以修改数据。使用场景悲观锁适用于写操作较多的场景或者当数据冲突可能性较高时。它可以在数据库层面实现如行锁、表锁等。优点能够有效防止数据冲突确保数据的一致性。缺点如果锁的粒度过大或持有时间过长可能导致并发性能下降和资源浪费。 乐观锁 (Optimistic Locking) 概念乐观锁是基于乐观态度的数据并发控制机制。它总是假设最好的情况即在读取数据和提交更新之间其他事务不会修改数据。因此它不会在读取数据时加锁而是在更新数据时检查是否有其他事务已经修改了数据。工作原理通常通过版本号、时间戳等机制实现。当事务想要更新数据时它会检查数据的版本号是否与自己最初读取的版本号相匹配。如果匹配说明没有其他事务修改过数据可以进行更新否则更新会被拒绝。使用场景乐观锁适用于读操作较多、写操作较少的场景或者当数据冲突可能性较低时。它通常在应用层面实现。优点在高并发场景下可以提高性能因为它减少了不必要的锁等待时间。缺点如果有很多写操作或者数据冲突频繁发生可能导致大量的重试和回滚从而降低性能。
实战中使用
悲观锁在关系型数据库中如MySQL可以使用SELECT ... FOR UPDATE语句对选定的行或表加锁。在Java中可以使用synchronized关键字或ReentrantLock等来实现悲观锁。乐观锁可以在应用层面实现例如在更新数据时检查数据的版本号是否发生变化。在MyBatis-Plus中可以通过OptimisticLockerInnerInterceptor插件来简化乐观锁的使用。
2、mybatis-plus实现乐观锁
MyBatis-plus本身并不直接实现悲观锁或乐观锁而是提供了与数据库的交互机制使得开发者能够在应用中实现这两种锁策略。但是为什么我们经常会看到 MyBatis 与乐观锁的结合而与悲观锁的结合较少呢这主要是因为两者在使用场景和适用性上的差异。
悲观锁 悲观锁主要在数据库层面实现例如通过 SQL 语句。当使用悲观锁时事务在读取数据时就会加锁确保在此期间其他事务不能修改数据。这涉及到数据库的并发控制和锁定机制与 MyBatis 的 ORM 功能关系不大。由于悲观锁的实现更多地依赖于数据库本身的功能因此 MyBatis 在这方面并没有太多可以增加的价值。 乐观锁 乐观锁通常在应用层面实现需要开发者检查数据的版本号、时间戳等来判断数据是否在读取后被其他事务修改。MyBatis-Plus 提供的 OptimisticLockerInnerInterceptor 插件可以简化这一过程帮助开发者更容易地在应用中实现乐观锁。由于乐观锁的实现更多地依赖于应用逻辑MyBatis 在这方面的插件和工具可以为开发者带来便利。
总结MyBatis 本身并不防止悲观锁或乐观锁而是提供了与数据库的交互机制。悲观锁主要依赖于数据库的功能来实现而乐观锁则可以在应用层面得到 MyBatis-Plus 等工具的帮助。
乐观锁的基础使用
MyBatis-Plus 提供了一个内置的乐观锁插件 OptimisticLockerInnerInterceptor 来帮助简化乐观锁的实现。以下是使用 MyBatis-Plus 实现乐观锁的基本步骤
1.添加乐观锁插件 在你的 MyBatis-Plus 配置中添加乐观锁插件。
Configuration
MapperScan({com.ds.blog.system.mapper,com.ds.blog.admin.mapper})
public class MybatisPlusConfig {Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor mybatisPlusInterceptor new MybatisPlusInterceptor();//乐观锁插件mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;} 2.标记乐观锁字段 在你的实体类中使用 Version 注解来标记作为乐观锁字段的属性通常是版本号或时间戳。
public class Entity { Version private Integer version; // 其他字段和方法
}更新操作 当你尝试更新数据时MyBatis-Plus 会自动检查乐观锁字段。如果数据的版本号与你最初读取的版本号不匹配更新会被拒绝并抛出 OptimisticLockException 异常。处理乐观锁异常 在你的业务代码中需要捕获并处理 OptimisticLockException 异常。通常的做法是重试更新操作或通知用户数据已被其他事务修改。自定义乐观锁逻辑 如果需要更复杂的乐观锁逻辑你可以实现自己的乐观锁拦截器并覆盖默认的行为。
注意乐观锁策略的成功与否还取决于你的并发控制策略和业务场景。
自定义乐观锁拦截器
具体步骤如下
1.创建自定义拦截器类 首先你需要创建一个类来实现 MyBatis-Plus 的 InnerInterceptor 接口。这个接口定义了一些方法允许你在 SQL 执行的不同阶段插入自定义逻辑。
import com.baomidou.mybatisplus.core.parser.SqlInfo;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*; import java.util.Properties; Intercepts({Signature(type Executor.class, method update, args {MappedStatement.class, Object.class})})
public class CustomOptimisticLockInterceptor implements InnerInterceptor { // 你的自定义逻辑将在这里实现
} 2.实现拦截方法 在你的自定义拦截器类中你需要实现 processBefore 和 processAfter 方法。这些方法在 SQL 执行之前和之后被调用允许你插入自定义逻辑。在这个例子中我们关注 processBefore 方法因为它允许我们在更新操作之前检查乐观锁。
Override
public void processBefore(Executor executor, MappedStatement ms, Object parameter, String sql, SqlInfo sqlInfo) { // 获取当前事务尝试更新的实体对象 Entity entity (Entity) parameter; // 获取原始版本号通常从数据库中读取 int originalVersion entity.getVersion(); // 检查版本号是否已经被修改意味着有其他事务已经更新了这条记录 if (originalVersion ! entity.getVersion()) { throw new OptimisticLockException(数据已被其他事务修改); } // 如果需要检查其他字段或执行其他逻辑可以在这里添加代码
} 3.注册自定义拦截器 在你的 MyBatis-Plus 配置中你需要注册你的自定义拦截器以便它能够被正确地应用到你的 SQL 执行过程中。
Configuration
MapperScan({com.ds.blog.system.mapper,com.ds.blog.admin.mapper})
public class MybatisPlusConfig {Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor mybatisPlusInterceptor new MybatisPlusInterceptor(); mybatisPlusInterceptor.addInnerInterceptor(new CustomOptimisticLockInterceptor());return mybatisPlusInterceptor;}