我试图按顺序实施乐观锁定,以避免丢失更新情况。在我的应用程序中,当两个用户获取相同的记录,而第一个用户通过一些更改对其进行更新时。查看相同记录的第二个用户看不到此更改,并且他自己进行了一些更改并更新了该记录。因此,第一人称更改丢失。为了防止这种情况,我写了以下内容,但问题仍然存在。我是这个概念的新手,无法发现问题。
我试图通过阅读doc
11.3.4 来实现这一目标。自定义自动版本控制部分。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="annotatedClasses">
<list>
<value>server.bo.Dept</value>
<value>server.bo.Emp</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</bean>
<bean id="deptDAO" class="server.dao.DeptDAOImpl">
<property name="hibernateTemplate" ref="hibernateTemplate"/>
</bean>
</beans>
@Entity
@Table(name = "Dept")
@org.hibernate.annotations.Entity(dynamicUpdate = true,optimisticLock = OptimisticLockType.ALL)
public class Dept{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
Long id;
@OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER, mappedBy = "deptId")
@Fetch(FetchMode.SELECT)
@OrderBy(value = "id DESC")
List<Emp> Emplist;
public Dept() {}
// Getters and setters
}
public class DeptDAOImpl extends HibernateDaoSupport implements DeptDAO {
@Transactional(readOnly = true, propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)
public Dept getDeptById(Long id) {
Object param[] = new Object[]{id};
String query = "select d from Dept d where d.id=? and d.deleted='0'";
List<Dept> deptDetailsList = getHibernateTemplate().find(query,param);
Dept deptDetails = null;
if(deptDetailsList !=null && deptDetailsList .size()>0)
deptDetails = (Dept)deptDetailsList.get(0);
return deptDetails ;
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)
public long updateDept(Dept dept) {
if (dept.getId() == null) {
getSession().save(dept);
} else {
getSession().update(dept);
}
if (dept.getEmplist() != null) {
final int size = dept.getEmplist().size();
for (int i = size - 1; i >= 0; i--) {
Emp emp = dept.getEmplist().get(i);
if (emp.getDeptId() == null) {
emp.setDeptId(dept.getId());
}
if (RecordStatus.NEW.equals(emp.getRecordStatus())) {
getSession().save(emp);
} else if (RecordStatus.DELETED.equals(emp.getRecordStatus())) {
getSession().delete(emp);
} else if (RecordStatus.MODIFIED.equals(emp.getRecordStatus())) {
getSession().update(emp);
}
}
}
return dept.getId();
}
}
提前致谢
JPA / Hibernate
Optmistic锁定的工作方式是使用某个字段来存储上次修改的版本(例如,时间戳,long),然后将会话中实体的版本与数据库中的实体进行比较,以查看是否可以保存更改。
为此,您需要在实体中使用@Version注释字段。
参见以下示例。
http://www.javacodegeeks.com/2012/11/jpahibernate-version-based-optimistic-
concurrency-control.html
为了使它在Web应用程序中起作用,需要进一步考虑,但是,好像两个人加载了相同的实体进行编辑,然后过一会儿提交他们的编辑,他们很可能都会成功,除非您使用某种长时间运行的会话,否则该实体正在编辑的文件将从表单提交的数据库中重新加载,填充和保存。
例如,修订版1中的实体
因此,要使此工作正常进行,您可以看一下提交一个隐藏字段的表单,该表单在存储实体修订版本时将其存储。因此,在上面的最后一步,当用户1提交时,修订字段将被设置回1,并且更新将失败,因为数据库中的记录在r2处。
我有一个带有和的微服务。我使用注释对中的表执行操作。我遇到的问题是保存操作花费了太多的时间,所以我希望读取操作不被它阻塞。注意,保存是通过持久化实体来执行的。 当前,在所有并发保存操作完成之前,所有读取操作都不会返回结果,这意味着表被锁定。相反,我希望实现乐观锁定。我怎样才能做到呢?
我读到我们可以使用<code>@version</code>在hibernate中使用version字段实现乐观锁定。然后,通过阅读悲观锁定,我知道了<code>org.hidbernate。LockMode</code>类,它有一些选项,如<code>LockMod。我们可以在中指定的OPTIMISTICetc。 所以我的问题是我是否需要同时使用和?
我有一个用Tapestry5(javawebframework)和Hibernate制作的web应用程序。现在我尝试添加乐观锁定。所以我添加了一个版本属性,乐观的锁定可以工作,所以这很容易,很快。 但是,由于我的web应用程序使用“每个请求一个会话”模式,我不确定利用这种乐观锁定的最佳方式是什么。 发生了什么: 用户 A 打开包含表单的页面,该表单加载了来自实体 A(版本 1)的值。 UserB打
我有一个这样的实体: 我有一个生成HQL的代码: 执行更新的代码: 问题: 乐观锁在这里出现吗?在上述情况下,Hibernate是否会自动处理乐观锁定(运行HQL且没有会话)? 如果上述情况不正确,我需要自己实现:我阅读了Hibernate文档,其中说,我需要用注释一个字段。但是我应该专门为此在表中添加这个新字段吗?或者我可以为注释指定任何现有字段?这里有什么特殊处理吗? 在乐观锁定期间抛出的异常
1. 前言 在锁一节中,我们从粒度和管理两个角度来阐述了锁。如果你还不熟悉锁,请先阅读该小节,再来进行本小节的学习。 本小节我们将继续深挖锁,以开发者和实战的角度来谈锁。 2. 为什么需要锁 2.1 什么是数据竞争 在本节的开头,我们来谈一谈为什么开发程序需要使用锁?如果你有一点并发编程的基础,又或者对多线程有一点熟悉,那么你肯定知道答案,那就是数据竞争。 2.2 数据竞争实例 我们举一个生活的例
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作 乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。 乐观锁与悲观锁的具体区别: http://www.cnblogs.com/Bob-FD/p/3352216.html