从jOOQ 手册中至少我不清楚如何正确配置乐观锁定。
<!-- All table and view columns that are used as "version" fields for
optimistic locking (A Java regular expression. Use the pipe to separate several expressions).
See UpdatableRecord.store() and UpdatableRecord.delete() for details -->
<recordVersionFields>REC_VERSION</recordVersionFields>
Run Code Online (Sandbox Code Playgroud)
及以下
recordVersionFields: Relevant methods from super classes are overridden to return the VERSION field
Run Code Online (Sandbox Code Playgroud)
它到底意味着什么?有人可以举个例子吗?
想象一下,如果有这张表,例如:
CREATE TABLE "users" (
"id" INTEGER DEFAULT nextval('global_seq') NOT NULL,
"code" TEXT NOT NULL,
"version" INTEGER NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
我应该在 pom.xml 中放入什么recordVersionFields?
<database>
<inputSchema>PUBLIC</inputSchema> …Run Code Online (Sandbox Code Playgroud) 我想知道如何使用JPA(toplink essentials)从服务器到客户端处理实体类中的乐观锁版本属性,反之亦然.
这是场景.
从浏览器用户发送请求到服务器,要求编辑个人用户信息.
服务器处理请求并将结果返回给浏览器.服务器代码类似于:
EntityManager em = EmProvider.getInstance().getEntityManagerFactory().createEntityManager();
用户u =(用户)em.find(User.class,myUserId);
回报你; //回复浏览器
在这里,我的困惑是User表有"version"列optimistic locking.
这意味着版本字段的值也会被发送回客户端,即使客户端(我或任何人)永远不会使用它.版本字段将用于服务器端代码.
那么将版本号发送给客户端是否正确?因为否则我无法弄清楚如何检查版本号,以防用户点击带有修改数据的网页上的"更新"按钮.
如果您需要更多说明,请告诉我.
我想通过使用乐观锁定来处理并发执行.我@Version在我的实体类中包含了注释.
在我的代码中,我同时运行两个线程.有时它正确执行.有时它是投掷org.eclipse.persistence.exceptions.OptimisticLockException和javax.persistence.OptimisticLockException.
public class StudentCreation implements Runnable {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("jpaApp");
Student student = null;
@Override
public void run() {
for (int i = 1; i <= 2; i++) {
try {
if (i % 2 == 0) {
update("XYZ");
} else {
update("ABC");
}
} catch (Exception e) {
System.out.println("Update exception");
}
}
}
// main method
public static void main(String ar[]) {
StudentCreation std1 = new StudentCreation();
// creating two threads …Run Code Online (Sandbox Code Playgroud) jpa locking eclipselink optimistic-locking optimistic-concurrency
更新提供的实体的EJB方法(使用CMT):
@Override
@SuppressWarnings("unchecked")
public boolean update(Entity entity) throws OptimisticLockException {
// Code to merge the entity.
return true;
}
Run Code Online (Sandbox Code Playgroud)
javax.persistence.OptimisticLockException如果检测到并发更新,则将抛出,这将由调用者(托管bean)精确处理.
public void onRowEdit(RowEditEvent event) {
try {
service.update((Entity) event.getObject())
} catch(OptimisticLockException e) {
// Add a user-friendly faces message.
}
}
Run Code Online (Sandbox Code Playgroud)
但这样做会使javax.persistence表达层上的API 产生额外的依赖性,这是一种导致紧密耦合的设计气味.
应该包装哪个例外,以便完全省略紧耦合问题?或者是否有一种标准方法来处理此异常,这反过来又不会导致在表示层上强制执行任何服务层依赖性?
顺便说一句,我发现在EJB中(在服务层本身上)捕获此异常然后向客户端(JSF)返回一个标志值是笨拙的.
由于在CakePHP中似乎没有任何对乐观锁定的支持,我正在尝试构建实现它的行为.在对行为进行一些研究之后,我想我可以在beforeSave事件中运行查询以检查版本字段是否未更改.
但是,我宁愿通过更改update语句的WHERE子句来实现检查
WHERE id = ?
Run Code Online (Sandbox Code Playgroud)
至
WHERE id = ? and version = ?
Run Code Online (Sandbox Code Playgroud)
这样我就不必担心在我读取版本和执行更新的时间之间更改数据库记录的其他请求.这也意味着我可以进行一次数据库调用,而不是两次.
我可以看到该DboSource.update()方法支持条件,但从Model.save()不传递任何条件.
看起来我有几个选择:
beforeSave()并确保其不是防弹的.conditions键并将其传递给方法.optionsModel.save()DboSource.update()现在,我倾向于支持第二种选择,但这意味着我不能与其他用户分享我的行为,除非他们将我的黑客应用到他们的框架中.
我错过了一个更简单的选择吗?
我是新手使用"乐观锁定"机制 - 我使用的是hibernate(在Jboss中)和容器管理事务(CMT).我想在我的实体读取和实体更新之间处理这种情况,其他人在DB中更新同一个实体(即行).在这种情况下,我想抛出异常..
我用@Version注释了我的实体 - 就像
@Version
private Long version;
Run Code Online (Sandbox Code Playgroud)
现在,我很困惑,如果这对于版本管理来说已经足够了,或者我需要显式调用EntityManager.lock()api之类的
{
.
.
final QueryDTO queryDTO = entityManager.find(QueryDTO.class, id);
entityManager.lock(queryDTO, LockModeType.READ);
queryDTO.setStatus(updatedStatus);
entityManager.persist(queryDTO);
}
Run Code Online (Sandbox Code Playgroud)
提前致谢,
我有一个这样的方法:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void doSomeWork(){
Entity = entity = dao.loadEntity();
// do some related work
...
try {
dao.saveEntity(entity);
}
catch(StaleObjectStateException sose){
dao.flush(entity);
doSomeWork();
}
}
Run Code Online (Sandbox Code Playgroud)
我期望通过使用 REQUIRES_NEW 事务传播和显示的递归,StaleObjectStateException 最终会清除,但事实并非如此。
我如何从这个异常中恢复?
我正在开发一个使用ZooKeeper作为数据存储区的应用程序.对于应用程序中的一个方法,我需要使用乐观并发控件.例如,我需要实现一个获取znode数据的get方法,并使用znode数据版本进行乐观并发控制检查.据我所知,无法在一次操作中获取znode数据和znode数据版本.如果存在更高争用更新znode数据,则get方法将无法工作,因为获取znode数据后znode数据可能会更改.所以我问 - 有没有一种方法可以在一次操作中获得znode数据和znode数据版本(或znode stat)而不会在其间进行任何锁定尝试?
optimistic optimistic-locking optimistic-concurrency apache-zookeeper
[这是我看到的关于Spring MVC的常见问题列表,它们以类似的方式解决.我在这里发布了它们,所以我可以从其他问题中轻松地引用它们]
如何仅使用表单更新模型实体的几个字段?
如何在Spring MVC中使用Post-Redirect-Get模式,尤其是表单验证?
如何保护我的实体中的某些字段?
如何实现乐观并发控制?
spring-mvc post-redirect-get optimistic-locking optimistic-concurrency
我正在编写一些代码来生成序列号。我将读取并更新数据库中的一条记录,该记录保存下一个要生成的数字。由于我期望有不同的线程访问此记录,因此我只是将 @Version 标签添加到同一实体的 Timestamp 字段中,然后控制可能出现的 OptimisticLockExceptions。
另外,我的数据库中会有几条这样的记录,其中包含不同的序列号,可以根据业务创建或删除它们。
域对象如下所示:
@Entity
@Table(name="Preferences")
public class Preferences implements Serializable, DomainObject {
...
...
@Column(name="nextSerial")
private String nextSerial;
@Version
@Column(name="RefreshDate")
private Timestamp refreshDate;
...
Run Code Online (Sandbox Code Playgroud)
直到这里一切正常,当共享相同数据的另一个应用程序创建首选项记录时,问题就出现了。构建此应用程序时,@Version 列不存在,因此它将创建带有 Null 值作为刷新日期的记录。
我知道这一点,我尝试设置刷新日期并更新记录,还尝试删除并再次创建记录,但无论如何,我都会收到如下异常:
org.springframework.orm.jpa.JpaOptimisticLockingFailureException:异常 [EclipseLink-5001](Eclipse 持久性服务 - 2.6.1.v20150916-55dc7c3):org.eclipse.persistence.exceptions.OptimisticLockException 异常描述:尝试删除对象[com.core.domain.Preferences@5e092f04],但它在身份映射中没有版本号。
所以我的问题是,如何从我的应用程序中处理这个问题?在数据库中使用触发器来确保非空 @Version 是不可取的,更改其他应用程序也是不可取的。
我已经实现了一个带有 @version 注释的简单实体 ejb。我希望每次更新实体后版本号都会增加。
@Version
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
Run Code Online (Sandbox Code Playgroud)
但这似乎没有按预期工作。此外,每次读取实体时,版本号都会自动增加(!?)。我希望版本只会在提交后增加?
有人可以解释为什么我的版本在读取时也会增加吗?
java ×4
jpa ×4
hibernate ×2
cakephp ×1
eclipselink ×1
ejb ×1
java-ee ×1
jooq ×1
jsf ×1
locking ×1
optimistic ×1
php ×1
spring ×1
spring-data ×1
spring-mvc ×1
sql ×1