我正在使用HSQLDB v2.3.3和Hibernate v4.3.9.Final。我想验证FOR UPDATE是否在查询中有效。我的查询如下:
@NamedNativeQueries({
@NamedNativeQuery(name = "Building.lockBuildingByIdForUpdate", query = "SELECT b.* FROM building b WHERE b.id = :buildingId FOR UPDATE", resultClass = Building.class),
})
我的Java代码如下:
public Object createNew( String buildingId ) {
SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd hh:mm:ss,SSS" );
System.out.println( format.format( System.currentTimeMillis() ) + ", Before acquiring lock..." + Thread.currentThread().getName() + ", buildingId=" + buildingId );
buildingDao.lockBuildingsById(buildingId);
System.out.println( format.format( System.currentTimeMillis() ) + " After acquiring lock..." + Thread.currentThread().getName() + ", buildingId=" + buildingId );
//Some further Save data in the Database logic which I am omitting on purpose
}
我编写了一个测试用例,它产生如下两个线程:
executor.execute( new Runnable() {
@Override
public void run() {
System.out.println( "First Thread Started..." + Thread.currentThread().getName() + ", buildingId=" + buildingId );
Object job = getService().createNew( buildingId );
System.out.println( "First Thread Ended..." + Thread.currentThread().getName() + ", buildingId=" + buildingId );
}
} );
executor.execute( new Runnable() {
@Override
public void run() {
System.out.println( "Second Thread Started..." + Thread.currentThread().getName() + ", buildingId=" + buildingId );
Object job = getService().createNew( buildingId );
System.out.println( "Second Thread Ended..." + Thread.currentThread().getName() + ", buildingId=" + buildingId );
}
} );
我的期望是,无论哪个线程获得锁定,都必须是唯一一个继续完成交易的人。然后只有第二个线程必须继续自己的执行。
但是,这不是我所看到的。我看到线程几乎同时获得了锁。我的输出如下:
First Thread Started...pool-7-thread-1, buildingId=bldg_id_1
Second Thread Started...pool-7-thread-2, buildingId=bldg_id_1
2017-11-29 03:49:34,527, Before acquiring lock...pool-7-thread-2, buildingId=bldg_id_1
2017-11-29 03:49:34,527, Before acquiring lock...pool-7-thread-1, buildingId=bldg_id_1
2017-11-29 03:49:34,594 After acquiring lock...pool-7-thread-1, buildingId=bldg_id_1
2017-11-29 03:49:34,594 Retrieving SomeObject pool-7-thread-1, buildingId=bldg_id_1
2017-11-29 03:49:34,598 After acquiring lock...pool-7-thread-2, buildingId=bldg_id_1
2017-11-29 03:49:34,598 Retrieving SomeObject pool-7-thread-2, buildingId=bldg_id_1
2017-11-29 03:49:34,674 Got SomeObject pool-7-thread-2, buildingId=bldg_id_1
2017-11-29 03:49:34,674 Got SomeObject pool-7-thread-1, buildingId=bldg_id_1
2017-11-29 03:49:34,711 Saved newJob in DB pool-7-thread-2, buildingId=bldg_id_1
2017-11-29 03:49:34,711 Saved newJob in DB pool-7-thread-1, buildingId=bldg_id_1
Second Thread Ended...pool-7-thread-2, buildingId=bldg_id_1
First Thread Ended...pool-7-thread-1, buildingId=bldg_id_1
因此输出清楚地表明没有应用锁定,并且两个线程都能够获得相同的锁定。
我的问题:HSQLDB v2.3.3是否支持FOR UPDATE?我在互联网[SELECT FOR UPDATE in hsqldb using hibernate上看到了它。根据经验不同。