JPA规范并没有涉及悲观锁,如有需要,可以参考下面代码实现:
在数据库中准备一张lock表
,
用户通过页面锁定某个entity时
java app向lock表插入一条记录,包含该entity实例的标识(如主键),该entity类型的标识(比如表的名字或实体Bean对应的java类的全路径名),锁定时间等。
如果java app发现lock表中已经存在相关记录,java app要判断其是否已经超时,如果已经超时,则更新锁定时间,锁定成功,如果未超时则返回锁定失败。
用户通过UI修改、删除某个锁定的entity时
java app除了修改该entity的值外,同时删除lock表中相关记录,以释放entity上的锁。
LOCKS表
DROP TABLE LOCKS;
--==============================================================
-- Table: LOCKS
--==============================================================
CREATE TABLE LOCKS
(
TB_NAME VARCHAR(500) not null,
PK_VALUE VARCHAR(40) not null,
KEYWD VARCHAR(40),
LOCKING_TIME DECIMAL(20),
TIMEOUT BIGINT,
constraint "P_KEY_1" primary key (TB_NAME, PK_VALUE)
);
@Stateless
public class CommonDaoBean implements CommonDaoLocal, CommonDaoRemote {
@PersistenceContext
EntityManager em;
/**
* lock an entity using key
*/
public boolean lock(Employ emp, String key, long timeOutInMilli) {
LocksId id = new LocksId(Employ.class.getCanonicalName(),""+emp.getPk());
Locks lock = new Locks(id,key,System.currentTimeMillis(),timeOutInMilli);
// 查询该entity是否已经被锁定
Locks currLock = em.find(Locks.class, id);
if(currLock == null){
em.persist(lock);
em.flush();// 'flush' must be called
return true;
}else{
// 判断现有锁是否已经超时
boolean currLockDead = System.currentTimeMillis() > (currLock.getLockingTime() + currLock.getTimeout());
if(currLockDead){
currLock.setLockingTime(System.currentTimeMillis());
em.merge(currLock);
em.flush();
return true;
}else{
return false;
}
}
}
/**
* update entity using a key, then release lock
*/
public void update(Employ emp, String key) {
LocksId id = new LocksId(Employ.class.getCanonicalName(),""+emp.getPk());
Locks currLock = em.find(Locks.class, id);
if(currLock == null){
throw new PessimisticLockingException("Entity not locked, entity:"+emp);
}
if(!currLock.getKeywd().equals(key)){
throw new PessimisticLockingException("Key '"+key+"' cannot open the lock on entity:"+emp);
}
em.merge(emp);
em.remove(currLock);
em.flush();
}
}
分享到:
相关推荐
Spring Data JPA 提供了内置的支持,可以在查询方法中通过 `Pageable` 参数实现分页和排序。 5. **Auditing**:Spring Data JPA 提供了审计功能,可以自动记录实体的创建时间和修改时间。这可以通过 `@CreatedDate`...
在标题和描述中提到的"jpa中hibernate实现相关jar包"是指一组完整的Hibernate库,这些库可以帮助开发者在项目中集成JPA和Hibernate,实现对数据库的高效操作。 以下是一些关键的Hibernate JPA相关jar包及其作用: ...
6. **分页和排序**:Spring Data JPA支持在查询结果中进行分页和排序,可以方便地通过Repository接口实现。 7. **存储过程**:Spring Data JPA也支持调用数据库存储过程,并将其结果转换为Java对象。 8. **JPA实体...
5. **事务管理(Transaction)**: 在JPA中,事务是通过`EntityManager`进行管理的。你可以使用`begin()`, `commit()`和`rollback()`方法来控制事务的边界。 6. **懒加载(Lazy Loading)与即时加载(Eager Loading...
在JPA中,我们可以通过`@IdClass`和`@Id`注解来实现联合主键。下面将详细介绍如何通过这些注解来实现联合主键。 ### 创建复合主键类 首先,需要创建一个复合主键类来存储需要组成联合主键的属性。这个类需要实现`...
总结来说,本项目展示了如何利用SpringBoot、SpringSecurity和JPA在IntelliJ IDEA环境下构建一个完整的用户角色权限管理系统,通过security.sql和security-jpa这两个关键组件,实现了数据初始化和核心业务逻辑的构建...
在本教程中,我们将深入探讨如何使用Spring Boot、JPA(Java Persistence API)以及Thymeleaf模板引擎实现一个简单的数据库操作,包括增删改查(CRUD)。Spring Boot简化了Java应用程序的开发过程,而JPA是Java平台...
在“Spring JPA 项目简单实现”中,我们主要关注的是如何将数据库中的学生信息展示到Web页面上。首先,我们需要配置Spring JPA。这通常包括以下步骤: 1. **添加依赖**:在项目的`pom.xml`或`build.gradle`文件中,...
标签中提到了"JPA注解参考_Oracle",这暗示了文件可能包含有关如何在JPA中使用注解来配置实体类以及在Oracle数据库上运行的相关信息。在JPA中,注解如`@Entity`用于标记实体类,`@Table`指定对应的数据库表,`@Id`...
在Spring Data JPA中,数据模型通常由@Entity注解的类表示,如`@Entity`的User类。使用`@Table`注解指定对应的数据库表,`@Id`标识主键,`@GeneratedValue`处理主键生成策略。 4. **Query方法命名规则** Spring ...
JPA是一个Java社区规范(Java Community Process JSR 220),用于在Java EE和Java SE环境中管理对象和关系数据库之间的映射,以及管理数据库中的数据持久化操作。JPA为对象/关系映射(ORM)提供了标准化的方法,可以...
- **实体(Entity)**: 在JPA中,实体是对数据库表的映射,通常是一个Java类,它的实例对应于数据库中的行。 - **实体管理器(EntityManager)**: 是JPA的核心组件,负责创建、查询和管理实体。 - **实体工厂...
在本示例中,我们将探讨如何使用Spring JPA来实现单表递归树形结构。 首先,我们需要理解递归树形结构。在数据库中,树形结构通常通过自关联来表示,即一个表的某个字段引用该表自身,形成一个层级关系。对于单表...
如何在Oralce,MySQL和PostgreSQL数据库上的Spring Boot应用程序和JPA中实现它 如何编写用于测试悲观锁定的集成测试。 先决条件: 码头工人 JDK8 +。 设置 从docker / db-up.sh启动Oracle数据库容器 使用“ docker ...
通过以上步骤,我们可以在Spring Boot应用中利用Spring Data JPA和`JpaRepository`轻松实现对数据库的访问,大大简化了数据访问层的代码。在实际项目中,还可以结合`Pageable`接口进行分页查询,或者使用`...
在实现继承关系时,需要注意以下几点: - **字段注解**:确保正确地在字段上使用`@Column`、`@Id`、`@GeneratedValue`等注解,以指定其在数据库中的映射。 - **关系映射**:如果子类中存在与其它实体的关系,需要...
在JPA中,通常通过`@Version`注解实现乐观锁。当一个实体被加载到内存时,JPA会记录该实体的版本号。当尝试更新该实体时,JPA会检查数据库中的版本号是否与内存中的版本号一致。如果一致,则更新并自动递增版本号;...
实体是JPA中的核心概念,代表了要持久化的Java对象。实体需满足特定条件,如使用`@Entity`注解标记,具备无参构造函数,且类和方法不可声明为final。此外,实体对象中的持久化属性应为非public访问级别,并通过...
基于springboot+jpa实现java后台api接口,点餐系统 基于springboot+jpa实现java后台api接口,点餐系统 基于springboot+jpa实现java后台api接口,点餐系统 基于springboot+jpa实现java后台api接口,点餐系统 基于...