具体的乐观锁定(Java)示例
我花了一上午的时间阅读了所有的顶级文章,但就我的一生而言,我仍然没有真正理解它 我知道乐观锁定包括添加一列来跟踪记录的“版本”,该列可以是时间戳、计数器或任何其他版本跟踪构造。但我仍然不理解如何确保写完整性(这意味着如果多个进程同时更新同一个实体,那么之后,该实体将正确地反映它应该处于的真实状态) 有人能提供一个具体的、易于理解的例子来说明乐观锁在Java中的使用方式(可能是针对MySQL数据库)。假设我们有一个具体的乐观锁定(Java)示例,java,concurrency,locking,optimistic-locking,Java,Concurrency,Locking,Optimistic Locking,我花了一上午的时间阅读了所有的顶级文章,但就我的一生而言,我仍然没有真正理解它 我知道乐观锁定包括添加一列来跟踪记录的“版本”,该列可以是时间戳、计数器或任何其他版本跟踪构造。但我仍然不理解如何确保写完整性(这意味着如果多个进程同时更新同一个实体,那么之后,该实体将正确地反映它应该处于的真实状态) 有人能提供一个具体的、易于理解的例子来说明乐观锁在Java中的使用方式(可能是针对MySQL数据库)。假设我们有一个人实体: public class Person { private Str
人
实体:
public class Person {
private String firstName;
private String lastName;
private int age;
private Color favoriteColor;
}
而Person
实例被持久化到people
MySQL表:
CREATE TABLE people (
person_id PRIMARY KEY AUTO_INCREMENT,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL, # } I realize these column defs are not valid but this is just pseudo-code
age INT NOT NULL,
color_id FOREIGN KEY (colors) NOT NULL # Say we also have a colors table and people has a 1:1 relationship with it
);
现在让我们假设有两个软件系统,或者一个系统上有两个线程,它们试图同时更新相同的Person
实体:
- 软件/线程#1正在尝试保留姓氏更改(从“John Smith”到“John Doe”)
- 软件/线程#2正在尝试保持最喜爱颜色的更改(从红色到绿色)
人员
和/或颜色
表上实现乐观锁定?(寻找特定的DDL示例)人员
/颜色
表?基本上,我希望看到乐观锁定的作用,并简单解释它的工作原理通常,当您研究乐观锁定时,您也会使用类库或其他支持的JPA实现 示例可以如下所示:
公共类人物{
私有字符串名;
私有字符串lastName;
私人互联网;
私人色彩偏爱色彩;
@版本
私人长版;
}
显然,如果您没有使用支持此功能的框架,那么添加@Version
注释是没有意义的
然后,DDL可能会被删除
创建表格人物(
人员id主键自动递增,
first_name VARCHAR(100)不为空,
last_name VARCHAR(100)NOT NULL,#}我知道这些列定义无效,但这只是伪代码
年龄INT不为空,
color_id外键(colors)NOT NULL,#假设我们还有一个colors表,并且人们与它有1:1的关系
版本BIGINT不为空
);
这个版本会发生什么?
updateperson SET lastName='marred',version=2,其中Person\u id=42,version=1;
执行语句后,检查是否更新了行。如果您这样做了,那么在您读取数据之后,没有其他人更改数据,否则其他人会更改数据。如果其他人更改了数据,您通常会收到您正在使用的库发出的警告
此异常应导致撤销所有更改,并重新启动更改值的过程,因为更新实体的条件可能不再适用
因此,没有碰撞:
- 乐观锁定并不是合并冲突更改的魔法。乐观锁定只会防止进程意外地被另一个进程覆盖更改
- 乐观锁实际上不是真正的DB锁。它只是通过比较version列的值来工作。您不会阻止其他进程访问任何数据,因此希望您得到
sOptimisticLockException
版本时间戳更新当前时间戳时的默认当前时间戳;
这样,实现乐观锁定的应用程序将注意到哑应用程序的更改
如果更新实体的频率高于时间戳的分辨率或Java对它的解释,那么这种方法可能无法检测到某些更改。另外,如果让Java生成新的时间戳
,则需要确保运行应用程序的所有计算机都处于完美的时间同步状态
如果您的所有应用程序都可以更改为整数、长。。。版本通常是一个很好的解决方案,因为它不会受到不同时钟设置的影响;-)
还有其他情况。例如,每次更改行时,您可以使用哈希,甚至可以随机生成字符串。重要的是,当任何进程为本地处理或缓存内保存数据时,不要重复值,因为该进程将无法通过查看数据来检测更改