我理解乐观和悲观锁定*之间的区别.现在有人可以向我解释我何时会使用其中任何一个?
这个问题的答案是否会根据我是否使用存储过程来执行查询而改变?
*但只是为了检查,乐观的意思是"在阅读时不要锁定桌子",悲观意味着"在阅读时锁定桌面".
我早上花了很多时间阅读谷歌在乐观锁定方面所做的所有热门文章,而对于我的生活,我仍然没有真正理解.
我理解乐观锁定涉及添加用于跟踪记录的"版本"的列,并且该列可以是时间戳,计数器或任何其他版本跟踪构造.但我仍然不明白如何确保WRITE完整性(意味着如果多个进程同时更新同一个实体,那么之后,实体正确地反映了它应该处于的真实状态).
有人可以提供一个具体的,易于理解的例子,说明如何在Java中使用乐观锁定(可能是MySQL数据库).假设我们有一个Person实体:
public class Person {
private String firstName;
private String lastName;
private int age;
private Color favoriteColor;
}
Run Code Online (Sandbox Code Playgroud)
并且这些Person实例会持久化到peopleMySQL表:
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 …Run Code Online (Sandbox Code Playgroud) 集群/分发Java服务器应用程序的最佳方法是什么?我正在寻找一种方法,允许您通过添加更多应用程序服务器和更多数据库服务器来水平扩展.
"最佳"解决方案允许您为单个节点编写Java应用程序,并希望"隐藏"访问/锁定共享数据的大部分细节.
在分布式环境中,最困难的问题总是归结为多个事务访问共享数据.似乎有两种常见的并发事务方法.
我一直在研究扩展解决方案(以及提供如何扩展的示例的一般应用程序),例如:
Terracotta似乎是最完整的解决方案,因为您可以"轻松"修改现有服务器应用程序以支持扩展(在定义@Root对象和@AutoLockRead/Write方法之后).问题是要真正从分布式应用程序中获得最大的性能,分布式系统的优化实际上并不是一个想法,你必须设计它,知道对象访问可能被网络I/O阻止.
为了正确扩展,似乎总是归结为分区数据和负载平衡事务,例如给定的"执行单元"(cpu core - > thread - >分布式应用程序节点 - > DB主节点)
似乎通过群集使任何应用程序可以正确扩展,您需要能够根据数据访问读/写对事务进行分区.人们提出了哪些解决方案来分发他们的应用程序数据(Oracle,Google BigTable,MySQL,数据仓库),以及一般如何管理分区数据(许多写入主数据库,以及更多读取数据库等).
在扩展数据持久层方面,在将数据划分给许多读者/多个编写者方面,哪种类型的配置最佳扩展(通常我会基于给定用户(或通常是您的任何核心实体)对数据进行分区"root"对象实体)由单个主DB拥有
java concurrency scalability transactions optimistic-locking
我有一个非常简单的Rails应用程序,允许用户在一组课程中注册他们的出勤.ActiveRecord模型如下:
class Course < ActiveRecord::Base
has_many :scheduled_runs
...
end
class ScheduledRun < ActiveRecord::Base
belongs_to :course
has_many :attendances
has_many :attendees, :through => :attendances
...
end
class Attendance < ActiveRecord::Base
belongs_to :user
belongs_to :scheduled_run, :counter_cache => true
...
end
class User < ActiveRecord::Base
has_many :attendances
has_many :registered_courses, :through => :attendances, :source => :scheduled_run
end
Run Code Online (Sandbox Code Playgroud)
ScheduledRun实例具有有限数量的可用位置,一旦达到限制,就不能再接受更多的考勤.
def full?
attendances_count == capacity
end
Run Code Online (Sandbox Code Playgroud)
attendances_count是一个计数器缓存列,包含为特定ScheduledRun记录创建的出勤关联数.
我的问题是,当一个或多个人同时尝试在课程中注册最后一个可用位置时,我不完全知道确保不会发生竞争条件的正确方法.
我的考勤控制器如下所示:
class AttendancesController < ApplicationController
before_filter :load_scheduled_run
before_filter :load_user, :only => :create
def new
@user = User.new
end
def …Run Code Online (Sandbox Code Playgroud) 我想知道在无法在请求之间保留具有特定版本的实体实例的系统中,实现乐观锁定(乐观并发控制)的最佳方法是什么。这实际上是一个非常常见的场景,但是几乎所有示例都基于在请求之间(在http会话中)保存已加载实体的应用程序。
如何在尽可能少的API污染的情况下实现乐观锁定?
栈是带有JPA(休眠)的Spring,如果这有任何关系的话。
@Version仅使用时出现问题在许多文档中,您似乎所需要做的就是用装饰一个字段,@Version并且JPA / Hibernate将自动检查版本。但是,只有将加载的对象及其当前版本保存在内存中,直到更新更改了同一实例,这才起作用。
@Version在无状态应用程序中使用时会发生什么:
id = 1并获取Item(id = 1, version = 1, name = "a")id = 1并获取Item(id = 1, version = 1, name = "a")Item(id = 1, version = 1, name = "b")EntityManager返回的项目Item(id = 1, version = 1, name = "a"),它更改name和持久化Item(id = 1, version = 1, name = "b")。Hibernate将版本增加到 …java hibernate jpa optimistic-locking optimistic-concurrency
我使用Spring 2.5和Hibernate JPA实现Java和"容器"管理事务.
我有一个"用户提交后"方法,它在后台更新数据,无论是异常ConcurrencyFailureException还是StaleObjectStateException异常都需要提交,因为它永远不会显示给客户端.换句话说,需要将乐观锁定变为悲观.(如果方法执行需要更长的时间并且有人在其他事务中更改了数据,则可能发生)
我读了很多关于幂等的东西,如果异常搜索DEFAULT_MAX_RETRIES或6.2.7则重试.示例或第14.5章.重试.我也在这里和这里找到了stackoverflow .
我试过这个:
public aspect RetryOnConcurrencyExceptionAspect {
private static final int DEFAULT_MAX_RETRIES = 20;
private int maxRetries = DEFAULT_MAX_RETRIES;
Object around(): execution( * * (..) ) && @annotation(RetryOnConcurrencyException) && @annotation(Transactional) {
int numAttempts = 0;
RuntimeException failureException = null;
do {
numAttempts++;
try {
return proceed();
}
catch( OptimisticLockingFailureException ex ) {
failureException = ex;
}
catch(ConcurrencyFailureException ex) { …Run Code Online (Sandbox Code Playgroud) 假设我想实现某种乐观锁定并使用ETag来指示最新的资源状态.这意味着,客户端在进行更新If-Match时将使用标头PUT.
根据HTTP规范,412 Precondition failed如果为If-Match标头提供的ETag 与资源的当前状态不匹配,则服务器必须返回.
然而,409 Conflict似乎更接近我想要在语义上表达的内容,特别是因为它给出了在响应中包含的指南.
409如果未能匹配If-Match标题中提供的ETag,那么返回是否非常错误?
我正在编写一个Web应用程序,例如,两个不同的用户可以更新列表中的事情列表.我已经意识到,乐观锁定机制最有效,因为我不期望高争用.
我在看事务隔离级别,现在我有点困惑.看起来不同的事务隔离级别也解决了类似的问题.
这两个不同的概念如何相互关联?如果可能,举个简单的例子.
database concurrency optimistic-locking isolation-level pessimistic-locking
我正在将我的应用程序从App Engine数据存储区移植到MongoDB后端,并对"文档更新"的一致性提出疑问.我知道一个文档的更新都是原子的和隔离的,但有没有办法保证它们在不同的副本集中"一致"?
在我们的应用程序中,许多用户可以(并且将会)在一次更新期间通过向其中插入一些嵌入文档(对象)来同时尝试更新一个文档.我们必须确保这些更新发生在所有副本逻辑一致的方式,即当一个用户"把"几嵌入文档到主文件,其他用户可以把自己嵌入文档的父文档中,直到我们确保他们已经阅读并收到第一个用户的更新.
所以我的意思是一致的是,我们需要一种方法来确保如果两个用户试图在一个文档进行更新恰好在同一时间,MongoDB中只允许这些更新要经过的一个,并丢弃另一个(或至少可以防止两者发生.我们不能在这里使用标准的"分片"解决方案,因为单个更新不仅仅包含增量或减量.
保证一个特定文档一致性的最佳方法是什么?
我有一个关于Hibernate中乐观锁定的问题.我试图深入了解Hibernate的乐观锁定,但我有一个疑问.Hibernate使用版本方法(整数或时间戳)来实现乐观锁定.要配置,您可以使用@Version注释(或xml配置)并创建版本属性.另一个选项是使用optimistic-lock ="all"属性进行配置而不进行版本控制.
我的问题是你没有定义任何版本控制属性,也没有指定一个乐观锁属性,在这种情况下哪个策略使用Hibernate?Pessimistc Locking我很确定不行,所以我认为这是乐观锁定但不知道如何.
非常感谢您的关注.
concurrency ×4
java ×4
database ×2
hibernate ×2
locking ×2
transactions ×2
activerecord ×1
aspectj ×1
consistency ×1
http ×1
jpa ×1
mongodb ×1
rest ×1
scalability ×1
spring ×1
sql-server ×1
web ×1