乐观锁与悲观锁

乐观锁和悲观锁是处理数据库并发操作的两种不同策略

乐观锁

乐观锁的核心思想是“乐观”,它假设在数据处理过程中,冲突发生的概率较低。因此,乐观锁不会在事务开始时就锁定数据,而是在数据提交时检查是否有其他事务修改过这些数据。如果数据未被修改,则事务可以成功提交;如果数据被其他事务修改了,则当前事务需要重新执行或放弃。乐观锁通常通过版本号(version)或时间戳(timestamp)来实现,每次更新数据时,版本号或时间戳都会相应地增加。这样,当事务尝试更新数据时,它会检查版本号或时间戳是否与开始时相同,如果不同则说明数据已被其他事务修改。

import java.util.concurrent.TimeUnit;public class OptimisticLockExample {private static int balance = 100;private static int version = 1;public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread(() -> updateBalance(50));Thread thread2 = new Thread(() -> updateBalance(30));thread1.start();thread2.start();thread1.join();thread2.join();System.out.println("Final balance: " + balance);}public static void updateBalance(int amount) {int currentVersion = version;// 模拟业务逻辑,更新余额int newBalance = balance + amount;// 模拟其他事务可能对数据进行修改的情况try {TimeUnit.SECONDS.sleep(2); // 模拟等待2秒} catch (InterruptedException e) {e.printStackTrace();}// 检查版本号是否发生变化if (version == currentVersion) {// 没有变化,可以更新数据balance = newBalance;version++;System.out.println("Balance updated successfully!");} else {// 版本号发生变化,说明有其他事务修改了数据,需要回滚System.out.println("Data has been modified by another transaction. Rollback.");}}
}

悲观锁:

悲观锁是一种预防性的策略,它的核心思想是在数据被访问时加锁,以防止其他事务或进程同时修改同一数据。这通常通过数据库提供的锁机制来实现,确保在任一时刻只有一个事务能够对数据进行写操作。

悲观锁的实现通常涉及到数据库中的行级锁或表级锁。行级锁是锁定特定行,而表级锁则是锁定整张表。悲观锁在数据被读取时就加上锁,直到事务结束才会释放,这样可以保证在事务执行期间不会有其他事务对数据进行修改。这种机制适用于写操作频繁、冲突概率高的环境,因为它可以有效地防止冲突发生,但可能会影响并发性能。

与乐观锁相比,悲观锁在数据处理上更为保守,总是假设共享资源会被修改,因此它在数据操作前就加上锁。乐观锁则相反,它假设共享资源不会被修改,只在提交时验证。

悲观锁是一种更为保守的并发控制策略,适用于对数据一致性要求较高的情景。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class PessimisticLockExample {private static final String DB_URL = "jdbc:mysql://localhost:3306/mydatabase";private static final String DB_USER = "username";private static final String DB_PASSWORD = "password";public static void main(String[] args) {try (Connection connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {connection.setAutoCommit(false); // 关闭自动提交// 获取悲观锁String selectQuery = "SELECT * FROM users WHERE id = 1 FOR UPDATE";PreparedStatement selectStatement = connection.prepareStatement(selectQuery);ResultSet resultSet = selectStatement.executeQuery();if (resultSet.next()) {int balance = resultSet.getInt("balance");int newBalance = balance + 50;// 更新余额String updateQuery = "UPDATE users SET balance = ? WHERE id = 1";PreparedStatement updateStatement = connection.prepareStatement(updateQuery);updateStatement.setInt(1, newBalance);updateStatement.executeUpdate();connection.commit(); // 提交事务System.out.println("Balance updated successfully!");} else {System.out.println("User not found.");}} catch (SQLException e) {e.printStackTrace();}}
}

上述示例中,我们使用了MySQL数据库作为示例。首先,我们通过FOR UPDATE子句获取了悲观锁,确保在事务执行期间不会有其他事务对数据进行修改。然后,我们执行查询操作并获取用户的余额信息。接下来,我们更新余额并提交事务。如果在事务执行期间有其他事务尝试修改同一行数据,将会被阻塞直到当前事务完成。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/748734.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第二十章 构建和配置 Nginx (UNIX® Linux macOS)

文章目录 第二十章 构建和配置 Nginx (UNIX Linux macOS)Assumptions安装为CSP构建Nginx Web服务器 第二十章 构建和配置 Nginx (UNIX Linux macOS) 本页介绍如何构建和配置 Nginx Web 服务器,以便与 UNIX、Linux 或 macOS 上的 InterSystems Web Gateway 一起使用…

pta-分寝室

目录 输入格式: 输出格式: 输入样例 1: 输出样例 1: 输入样例 2: 输出样例 2: 思路 学校新建了宿舍楼,共有 n 间寝室。等待分配的学生中,有女生 n0​ 位、男生 n1​ 位。所有待…

Android Framework 之 Python

当然可以,我会尽量提供更详细的内容,并增加更多的例子和解释。以下是更详细的Python语言教程: Python语言教程 一、Python简介 Python是一种高级编程语言,由Guido van Rossum于1989年底发明,第一个公开发行版发行于…

【快捷部署】002_Flink(1.17.2)

📣【快捷部署系列】002期信息 编号选型版本操作系统部署形式部署模式002Flink1.17.2CentOS 7.Xtgz包单机 👉 演示视频 Flink一键安装(本地模式) install-flink.sh 脚本内容 #!/bin/bash ####变量 ###执行脚本的当前目录 mydir$…

【linux】搜索所有目录和子目录下的包含.git的文件并删除

一、linux命令搜索所有目录和子目录下的包含.git的文件 在Linux系统中,要搜索所有目录和子目录下的包含.git的文件,可以使用find命令。find命令允许指定路径、表达式和操作来查找文件。 以下是使用find命令搜索包含.git的文件的方法: 1. 基…

权衡后台数据库设计中是否使用外键

目录 引言 外键简介 对比 真实后台项目中的权衡 结论 引言 在大学学习数据库课程时,我们会早早的接触到外键这一概念,同时我相信大部分人在懂了外键的概念后都会觉得外键很重要,在涉及多表一定要用,但后来在我接触到真实项目…

oracle基础-子查询 备份

一、什么是子查询 子查询是在SQL语句内的另外一条select语句,也被称为内查询活着内select语句。在select、insert、update、delete命令中允许是一个表达式的地方都可以包含子查询,子查询也可以包含在另一个子查询中。 【例1.1】在Scott模式下&#xff0…

Vue生成Canvas二维码

npm install qrcode在Vue组件中引入QRCode库:import QRCode from qrcode;在Vue组件的methods中创建一个方法来生成二维码: generateQRCode() {const canvas this.$refs.qrCodeCanvas; // 获取canvas DOM元素的引用const text Hello, World!; // 要生成…

JVM理解学习

参考视频 运行时数据区 JVM架构总览图 绿色的:方法区,堆,是所有线程共享的 黄色的: 虚拟机栈,本地方法栈,程序计数器,是线程私有的 程序计数器 程序计数器是一块较小的内存空间,物…

SpringBoot(异常处理)

SpringBoot(异常处理) 1.基本介绍 2.debug异常处理机制 1.找到 DefaultErrorViewResolver 2.下断点 3.debug启动,浏览器输出一个不存在的页面 4.第一次查找 error/404 1.查看目前要找的视图名 2.准备去查找资源 3.准备从四个默认存放静态资…

AcWing.505 火柴排队(离散化逆序对)

题目 涵涵有两盒火柴,每盒装有 n  根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为: ∑i1n(ai−bi)2 其中 ai表示第一列火柴中第 i个火柴的…

[COCI2016-2017#2] Prosječni 解题记录

[COCI2016-2017#2] Prosječni 解题记录 题意简述 构造一个 n n n \times n nn 的矩阵,使得每一行/列的平均都在这一行/列当中,并且矩阵内各个数字不相同。 题目分析 观察样例就可以轻松发现:当 n n n 为奇数时,矩阵内的各个…

开源漏扫工具:DependencyCheck

开源漏扫工具:DependencyCheck Dependency-Check 是 OWASP(Open Web Application Security Project)的一个实用开源程序,用于识别项目依赖项并检查是否存在任何已知的,公开披露的漏洞。 DependencyCheck是一个开源的…

【并查集】模版

【模板】并查集 - 洛谷 #include <bits/stdc.h> using namespace std; const int N2e59; int a[N]; int Find(int x) {if(xa[x]){return x;}else{a[x]Find(a[x]);return a[x];} } void push(int x,int y) {a[Find(x)]Find(y);return ; } int main() {int n,m; cin>>…

vsto 多插件通信

if (Target.Column 5){Thread.Sleep(5000);Target.Interior.ColorIndex 55;//触发另外一个插件Target.Application.Calculation XlCalculation.xlCalculationAutomatic;Thread.Sleep(5000);//这行执行完之后&#xff0c;才会触发另外一个Target.Interior.ColorIndex 54;} …

Python win32com.client.Dispatch打开Word文档并导出为 PDF时失败Command failed

Python win32com.client.Dispatch打开Word文档并导出为 PDF时失败Command failed 输出异常&#xff1a; (-2147352567, Exception occurred., (0, uMicrosoft Word, uCommand failed, uwdmain11.chm, 36966, -2146824090), None)调试之后&#xff0c;主要是下面几个原因: 路径…

前端实例:页面布局1(后端数据实现)

效果图 注&#xff1a;这里用到后端语言php&#xff08;页面是.php文件&#xff09;,提取纯html也可以用 inemployee_index.php <?php include(includes/session.inc); $Title _(内部员工首页); $ViewTopic 内部员工首页; $BookMark 内部员工首页; include(includes/…

Vue学习日记 Day6 —— Vuex

一、vuex概述 1、目标&#xff1a;明确vuex是什么&#xff0c;应用场景&#xff0c;优势 2、是什么&#xff1a;vuex是一个vue的状态管理工具&#xff0c;状态就是数据 (简述&#xff1a;vuex是一个插件&#xff0c;可以帮我们管理vue通用的数据) 3、场景&#xff1a; (1)…

物理隔离条件下,如何安全高效地进行内外网文件导入导出?

内外网文件导入导出通常指的是在内部网络&#xff08;内网&#xff09;和外部网络&#xff08;外网&#xff09;之间传输文件的过程。这在企业环境中尤其常见&#xff0c;因为内部网络通常包含敏感数据&#xff0c;而外部网络&#xff08;如互联网&#xff09;则允许更广泛的访…

基于 Spark 的电商用户行为分析系统

摘 要 针对传统的大数据处理框架 Hadoop 在执行计算任务时抽象层次低、运行速度慢、无法实时计算等问题, 提出了一种基于内存的分布式框架 Spark 作为计算引擎的方法。结合 Hadoop 框架中的分布式文件存储 技术,设计了一个电商用户行为分析系统。首先根据数据特点建立用户画…