use*_*759 17 java oracle spring hibernate jpa
如何@Lock为查询指定超时.我正在使用oracle 11g,我希望我可以使用类似的东西'select id from table where id = ?1 for update wait 5'.
我定义了这样的方法,
@Lock(LockModeType.PESSIMISTIC_WRITE)
Stock findById(String id);
Run Code Online (Sandbox Code Playgroud)
它似乎永远锁定.我开始javax.persistence.lock.timeout=0了LocalContainerEntityManagerFactoryBean.jpaProperties,但没有受到影响.
Sky*_*ker 17
要悲观锁定机构,设置锁定模式
PESSIMISTIC_READ,PESSIMISTIC_WRITE或PESSIMISTIC_FORCE_INCREMENT.如果无法获得悲观锁定,但锁定失败不会导致事务回滚,
LockTimeoutException则抛出a.可以使用javax.persistence.lock.timeout属性指定持久性提供程序等待获取数据库表锁定的时间长度(以毫秒为单位).如果获取锁定所需的时间超过此属性的值,
LockTimeoutException则将抛出a,但当前事务将不会标记为回滚.如果此属性设置为0,则持久性提供程序应抛出一个LockTimeoutExceptionif它无法立即获得锁定.如果
javax.persistence.lock.timeout在多个位置设置,则将按以下顺序确定值:
- 其中一个
EntityManager或的论点Query methods.@NamedQuery注释中的设置.Persistence.createEntityManagerFactory方法的论据.persistence.xml部署描述符中的值.
@Lock从Spring Data JPA 1.6版本开始,CRUD方法支持(事实上,已经有一个里程碑可用).有关详细信息,请参阅此票证.
使用该版本,您只需声明以下内容:
interface WidgetRepository extends Repository<Widget, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
Widget findOne(Long id);
}
Run Code Online (Sandbox Code Playgroud)
这将导致支持存储库代理的CRUD实现部分将配置的LockModeType应用于find(…)调用EntityManager.
Spring Data悲观@Lock注释仅适用于(如您所指出的)查询.我知道没有可以影响整个交易的注释.您可以创建一个使用悲观锁定findByOnePessimistic调用的方法,findByOne也可以更改findByOne为始终获得悲观锁定.
如果你想实现自己的解决方案,你可能会.在引擎盖下@Lock处理注释,通过LockModePopulatingMethodIntercceptor该注释执行以下操作:
TransactionSynchronizationManager.bindResource(method, lockMode == null ? NULL : lockMode);
Run Code Online (Sandbox Code Playgroud)
您可以创建一个具有ThreadLocal<LockMode>成员变量的静态锁管理器,然后在每个存储库中的每个方法都包含一个方面,该方法使用ThreadLocal中设置的锁定模式调用bindResource.这将允许您基于每个线程设置锁定模式.然后,您可以创建自己的@MethodLockMode注释,该方法将方法包装在一个方面,该方面在运行方法之前设置特定于线程的锁定模式,并在运行该方法后将其清除.
可以通过lock方法显式锁定实体对象:
em.lock(employee, LockModeType.PESSIMISTIC_WRITE);
Run Code Online (Sandbox Code Playgroud)
第一个参数是实体对象.第二个参数是请求的锁定模式.
TransactionRequiredException如果在调用lock时没有活动事务,则抛出A,因为显式锁定需要活动事务.
LockTimeoutException如果无法授予请求的悲观锁,则抛出A :
PESSIMISTIC_READ如果另一个用户(这是由另一EntityManager实例表示)当前持有的锁请求失败
PESSIMISTIC_WRITE该数据库对象上的锁.PESSIMISTIC_WRITE如果另一用户当前持有任一个锁定请求失败PESSIMISTIC_WRITE锁或PESSIMISTIC_READ该数据库对象上的锁.可以在以下范围(从全局到本地)中设置查询提示:
对于整个持久性单元 - 使用persistence.xml属性:
<properties>
<property name="javax.persistence.query.timeout" value="3000"/>
</properties>
Run Code Online (Sandbox Code Playgroud)
对于EntityManagerFactory - 使用createEntityManagerFacotory方法:
Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 4000);
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("pu", properties);
Run Code Online (Sandbox Code Playgroud)
对于EntityManager - 使用createEntityManager方法:
Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 5000);
EntityManager em = emf.createEntityManager(properties);
Run Code Online (Sandbox Code Playgroud)
或使用setProperty方法:
em.setProperty("javax.persistence.query.timeout", 6000);
Run Code Online (Sandbox Code Playgroud)
对于named query定义 - 使用hints元素:
@NamedQuery(name="Country.findAll", query="SELECT c FROM Country c",
hints={@QueryHint(name="javax.persistence.query.timeout", value="7000")})
Run Code Online (Sandbox Code Playgroud)
对于特定的查询执行 - 使用该setHint方法(在查询执行之前):
query.setHint("javax.persistence.query.timeout", 8000);
Run Code Online (Sandbox Code Playgroud)
您可以@QueryHints在Spring Data中使用:
@Lock(LockModeType.PESSIMISTIC_WRITE)
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="5000")})
Stock findById(String id)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15253 次 |
| 最近记录: |