我们决定在我们的Web应用程序中使用乐观锁定,以便增加并发性,而不使用悲观锁定.
我们现在正在寻找重试解决方案.
我们希望对我们当前的代码库产生尽可能小的影响.
我们在网上看到的解决方案之一是使用带注释的重试拦截器将方法标记为可重试.
问题是我们想要注释对它们有@Transactional注释的方法,但拦截器由于某种原因无法重试它们.(拦截器完美地重试非事务方法.)
所以:
1)是否有任何替代重试对我们的代码影响最小?
2)该解决方案是否有任何文档\教程?
3)是否可以重试@Transactional注释方法?
干杯!
在什么情况下通过Hibernate明确地从@OneToMany关系中排除乐观锁定?
我一直在阅读有关Hibernate的帖子,它基本上表示对子实体的任何更新都会导致对父实体的乐观锁定,这通常是不需要的.这里的关键词通常是 ......任何人都可以更准确地解释你何时或不需要乐观锁定这样的关系?
以下是用于演示乐观锁定排除的代码示例:
// Bars - these are specifically excluded from optimist lock
// for the object, since we don't want to obtain optimistic
// lock when we add a new bar
@OptimisticLock(excluded = true)
@OneToMany
@JoinColumn(name = "FOO_ID", nullable = false, updatable = false)
private List<FooBar> bars = new LinkedList<FooBar>();
Run Code Online (Sandbox Code Playgroud) 我是Hibernate和Spring的新手,在尝试学习Spring,Hibernate,Maven等时,我只知道如何使用所有这三个来运行一个hello world示例.基于我的基本理解,我被分配了一个执行乐观锁定的任务.据我搜索它,我只能看到我所需要的是在我的映射类中的xml和整数变量版本中添加版本标签并不是很困难.就像这样...
public class MyClass {
...
private int version;
...
}
Run Code Online (Sandbox Code Playgroud)
我的xml应该是这样的
<class name="MyClass">
<id ...>
<version name="version" column="VERSION" access="field">
...
</class>
Run Code Online (Sandbox Code Playgroud)
当第二个用户保存时,hibernate将自动处理版本控制,hibernate发现此用户正在处理陈旧数据并抛出StaleObjectException.
只是想提前确认我的理解.
如果有人可以为我指出一个问候世界的例子,那将会非常有帮助.
我还想提一下,我正在尝试实施"最后提交胜利"的场景
我知道乐观和悲观锁定是什么,但是当你编写java代码时,你是如何做到的?假设我使用Oracle和Java,我在JDBC中有任何方法可以帮助我做到这一点吗?我该如何配置这个东西?任何指针将不胜感激.
我试图了解调用EntityManager.lock(entity,LockModeType.READ)的效果.API文档对我来说听起来很混乱.
如果我必须并发线程并且线程1调用lock(实体,LockModeType.READ),那么线程2仍然可以读写实体吗?
到目前为止我学到了什么:
JPA1中的锁定类型READ与JPA2中的OPTIMISTIC相同.如果设置了这样的锁,EntityManager会在提交事务之前检查版本属性,但不会更新它.我找到了OPTIMISTIC锁定模式的解释:链接.搜索OPTIMISTIC(READ)LockMode示例.正如我所理解的那样,在线程1中设置读锁定对线程2 ... n没有影响.所有其他线程仍然可以读写实体.但是当线程1中的事务提交而另一个线程已更新实体时,线程1中的事务将被回滚.
我理解这是对的吗?
许多REST API提供搜索资源的功能.
例如,可以使用以下HTTP请求获取类型A的资源:
GET /A?prop1={value1}&prop2={value2}
Run Code Online (Sandbox Code Playgroud)
我正在使用乐观锁定,因此希望为A类型的每个返回资源返回一个版本.到目前为止,我在使用其ID仅获取一个资源时使用了ETag标头.
是否有一种HTTP方法可以在同一响应中为多个资源返回版本?如果没有,我应该在正文中包含版本吗?
谢谢,Mickael
编辑:我在网上发现,ETag通常是通过计算部分回复的哈希来生成的.这种方法非常适合我的情况,因为将计算返回集合的哈希值.但是,如果客户端决定更新集合中的一个元素,那么他应该将哪个ETag置于If-Match标头中?我认为包含各个元素的ETag是唯一的解决方案......
我想我已经淘汰了一切,但我不确定我是否完全理解OL以确定.一般来说,假设你和我在团队中保持最新状态.我在一个房间并决定节省时间我会自己更新foo.所以我开始更新它.一分钟后,您有相同的想法,并登录编辑页面以更新它.如果我先完成会怎么样?如果你先完成会怎么样?在它失败的配置中,它如何区分某人编辑和某人阅读.如果我catch重新加载以更新锁定,我将丢失所有更改,这是如何解决的?在这里,重做更新很简单,但可能它是更复杂的表单对象的一部分.
我的具体问题来自(最好我能说出来)在我的浏览器中加载了一个副本,后来忘记了它,然后我的控制台中的一个(也是锁定:0?)无法更新我的控制台中的陈旧对象错误.注意浏览器的事情.关上我的控制台.试图重新加载我的浏览器并得到陈旧的对象错误.这是失败的代码:
=> 7: self.update_attributes({
8: failed_view_attempts: self.failed_view_attempts += 1,
9: failed_view_at: Time.now
10: })
11: end
(byebug) self
#<Product id: 12... lock_version: 0>
#=> ActiveRecord::StaleObjectError (Attempted to update a stale object: Product.)
Run Code Online (Sandbox Code Playgroud)
我试过的事情:
要查看是否正在加载另一个实例,我puts "CALLED !!!!"在after_initialize回调中添加了它,但它只打印了一次.
并self.changed在从错误中抢救并检索后进行检查["updated_at", "failed_view_attempts", "failed_view_at"]
我读过马丁福勒的书章节 Optimistic Offline Lock
作者描述了以下示例(如果我理解正确的话):
有 2 个实体:Order和Client. 涉及2个交易(业务):
第一个交易计算订单的税额。税额取决于订单点和客户地址
第二笔交易更新客户端地址
这里的问题是,如果在计算税额时client更改地址order,结果可能会不一致。作者提供了两种基于乐观离线锁定的解决方案。其中之一是检查order和client在交易开始时的版本,并检查order和client版本在事务结束。但是这里作者警告我们必须使用REPEATABLE READ隔离级别或更高级别才能第二次读取版本。这是我的问题的一个原因。据我所知,如果我第二次读取任何行,我将得到相同的结果,因为在使用此隔离级别时,DB 会锁定我们之前读取的所有行。
请解释一下作者的想法。
java hibernate transaction-isolation optimistic-locking isolation-level
我得到以下堆栈跟踪:
org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Object of class [com.btfin.wrapcore.request.MFRequest] with identifier [2850448]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.btfin.wrapcore.request.MFRequest#2850448]
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:672)
at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)
Run Code Online (Sandbox Code Playgroud)
这是由于乐观的锁定异常.我可以解决这个的根本原因.
我的问题是 - 在这种情况下 - 异常处理将数据库连接设置为"已关闭".(这会导致我的连接池出现问题).
处理数据库异常的模式是什么,比如HibernateOptimisticLockingFailureException通过spring和hibernate冒泡并返回一个封闭的连接?
你知道Spring/Hibernate代码中的部分将连接设置为关闭吗?
spring hibernate database-connection exception-handling optimistic-locking
在工作中,我们正在开发一个RESTful应用程序,其中数据层将由Hibernate处理.但我们不确定如何处理实体更新.
我们计划做以下事情:
1)客户端通过id请求实体
2)Hibernate加载实体,请求的字段(总是带有版本)被复制到转换为JSON并发送到客户端的DTO
3)客户端管理一些字段并发送实体(与版本号)回到服务器.
4)服务器接收转换为DTO的JSON.
5)从Hibernate加载相应的实体,并将DTO的道具复制到实体.
=>即使设置了客户端的版本号,也始终会覆盖实体.这是否意味着我们总是必须自己检查客户端的版本号与已加载实例的版本号,而不是Hibernate这样做?
在具有会话的常规应用程序中,分离的实例保存在HttpSession中.每当客户端更新实体时,都会从HttpSession中检索实例,并更新一些属性.每当Hibernate提交更新时,如果版本号是<当前版本号,则抛出ObjectStaleException.
这里的问题是我们没有任何Http会话,因为我们试图成为RESTful.
是否有一个通用的解决方案来处理RESTful应用程序中的乐观锁定,而不是自己检查版本号?