HHH-13239 - The query hint javax.persistence.lock.timeout doesn't work correctly on HANA
Convert the lock wait timeout to seconds by dividing the timeout by 1000 (i.e. ignoring the fractions of a second)
This commit is contained in:
parent
a36df5f259
commit
0750716c87
|
@ -29,6 +29,7 @@ import java.sql.SQLException;
|
|||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Types;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
|
@ -1452,10 +1453,11 @@ public abstract class AbstractHANADialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public String getWriteLockString(int timeout) {
|
||||
if ( timeout > 0 ) {
|
||||
return getForUpdateString() + " wait " + timeout;
|
||||
long timeoutInSeconds = getLockWaitTimeoutInSeconds( timeout );
|
||||
if ( timeoutInSeconds > 0 ) {
|
||||
return getForUpdateString() + " wait " + timeoutInSeconds;
|
||||
}
|
||||
else if ( timeout == 0 ) {
|
||||
else if ( timeoutInSeconds == 0 ) {
|
||||
return getForUpdateNowaitString();
|
||||
}
|
||||
else {
|
||||
|
@ -1466,7 +1468,7 @@ public abstract class AbstractHANADialect extends Dialect {
|
|||
@Override
|
||||
public String getWriteLockString(String aliases, int timeout) {
|
||||
if ( timeout > 0 ) {
|
||||
return getForUpdateString( aliases ) + " wait " + timeout;
|
||||
return getForUpdateString( aliases ) + " wait " + getLockWaitTimeoutInSeconds( timeout );
|
||||
}
|
||||
else if ( timeout == 0 ) {
|
||||
return getForUpdateNowaitString( aliases );
|
||||
|
@ -1476,6 +1478,16 @@ public abstract class AbstractHANADialect extends Dialect {
|
|||
}
|
||||
}
|
||||
|
||||
private long getLockWaitTimeoutInSeconds(int timeoutInMilliseconds) {
|
||||
Duration duration = Duration.ofMillis( timeoutInMilliseconds );
|
||||
long timeoutInSeconds = duration.getSeconds();
|
||||
if ( duration.getNano() != 0 ) {
|
||||
LOG.info( "Changing the query timeout from " + timeoutInMilliseconds + " ms to " + timeoutInSeconds
|
||||
+ " s, because HANA requires the timeout in seconds" );
|
||||
}
|
||||
return timeoutInSeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryHintString(String query, List<String> hints) {
|
||||
return query + " with hint (" + String.join( ",", hints ) + ")";
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
public class HANADialectTestCase extends BaseUnitTestCase {
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-13239")
|
||||
public void testLockWaitTimeout() {
|
||||
HANAColumnStoreDialect dialect = new HANAColumnStoreDialect();
|
||||
|
||||
String sql = "select dummy from sys.dummy";
|
||||
|
||||
LockOptions lockOptions = new LockOptions( LockMode.PESSIMISTIC_WRITE );
|
||||
lockOptions.setTimeOut( 2000 );
|
||||
|
||||
Map<String, String[]> keyColumns = new HashMap<>();
|
||||
|
||||
String sqlWithLock = dialect.applyLocksToSql( sql, lockOptions, new HashMap<>() );
|
||||
assertEquals( sql + " for update wait 2", sqlWithLock );
|
||||
|
||||
lockOptions.setTimeOut( 0 );
|
||||
sqlWithLock = dialect.applyLocksToSql( sql, lockOptions, new HashMap<>() );
|
||||
assertEquals( sql + " for update nowait", sqlWithLock );
|
||||
|
||||
lockOptions.setTimeOut( 500 );
|
||||
sqlWithLock = dialect.applyLocksToSql( sql, lockOptions, new HashMap<>() );
|
||||
assertEquals( sql + " for update nowait", sqlWithLock );
|
||||
|
||||
lockOptions.setTimeOut( 1500 );
|
||||
sqlWithLock = dialect.applyLocksToSql( sql, lockOptions, new HashMap<>() );
|
||||
assertEquals( sql + " for update wait 1", sqlWithLock );
|
||||
|
||||
lockOptions.setAliasSpecificLockMode( "dummy", LockMode.PESSIMISTIC_READ );
|
||||
keyColumns.put( "dummy", new String[]{ "dummy" } );
|
||||
sqlWithLock = dialect.applyLocksToSql( sql, lockOptions, keyColumns );
|
||||
assertEquals( sql + " for update of dummy.dummy wait 1", sqlWithLock );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue