HHH-8786 - find, refresh, lock should throw LockTimeoutException or PessimisticLockException when lock problems occur
HHH-12570 - MariaDB 10.3 adds support for lock timeouts via WAIT plus NOWAIT
This commit is contained in:
parent
1570c71833
commit
9f4ff8ae90
|
@ -59,7 +59,8 @@ ext {
|
||||||
'jdbc.url' : 'jdbc:mysql://127.0.0.1/hibernate_orm_test'
|
'jdbc.url' : 'jdbc:mysql://127.0.0.1/hibernate_orm_test'
|
||||||
],
|
],
|
||||||
mariadb : [
|
mariadb : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.MariaDB102Dialect',
|
'db.dialect' : '',
|
||||||
|
// 'db.dialect' : 'org.hibernate.dialect.MariaDB102Dialect',
|
||||||
'jdbc.driver': 'org.mariadb.jdbc.Driver',
|
'jdbc.driver': 'org.mariadb.jdbc.Driver',
|
||||||
'jdbc.user' : 'hibernate_orm_test',
|
'jdbc.user' : 'hibernate_orm_test',
|
||||||
'jdbc.pass' : 'hibernate_orm_test',
|
'jdbc.pass' : 'hibernate_orm_test',
|
||||||
|
|
|
@ -207,6 +207,7 @@ tasks.withType( Test.class ).all { task ->
|
||||||
}
|
}
|
||||||
|
|
||||||
processTestResources {
|
processTestResources {
|
||||||
|
inputs.property( "db", db )
|
||||||
doLast {
|
doLast {
|
||||||
copy {
|
copy {
|
||||||
from( sourceSets.test.java.srcDirs ) {
|
from( sourceSets.test.java.srcDirs ) {
|
||||||
|
|
|
@ -7,11 +7,12 @@
|
||||||
package org.hibernate.dialect;
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
|
||||||
|
import org.hibernate.LockOptions;
|
||||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An SQL dialect for MariaDB 10.3 and later, provides sequence support.
|
* An SQL dialect for MariaDB 10.3 and later, provides sequence support, lock-timeouts, etc.
|
||||||
*
|
*
|
||||||
* @author Philippe Marschall
|
* @author Philippe Marschall
|
||||||
*/
|
*/
|
||||||
|
@ -58,4 +59,27 @@ public class MariaDB103Dialect extends MariaDB102Dialect {
|
||||||
return "select table_name from information_schema.TABLES where table_type='SEQUENCE'";
|
return "select table_name from information_schema.TABLES where table_type='SEQUENCE'";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getWriteLockString(int timeout) {
|
||||||
|
if ( timeout == LockOptions.NO_WAIT ) {
|
||||||
|
return getForUpdateNowaitString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( timeout > 0 ) {
|
||||||
|
return getForUpdateString() + " wait " + timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getForUpdateString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getForUpdateNowaitString() {
|
||||||
|
return getForUpdateString() + " nowait";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getForUpdateNowaitString(String aliases) {
|
||||||
|
return getForUpdateString( aliases ) + " nowait";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.sql.Types;
|
||||||
|
|
||||||
import org.hibernate.JDBCException;
|
import org.hibernate.JDBCException;
|
||||||
import org.hibernate.NullPrecedence;
|
import org.hibernate.NullPrecedence;
|
||||||
|
import org.hibernate.PessimisticLockException;
|
||||||
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.dialect.function.NoArgSQLFunction;
|
import org.hibernate.dialect.function.NoArgSQLFunction;
|
||||||
|
@ -525,6 +526,16 @@ public class MySQLDialect extends Dialect {
|
||||||
return new SQLExceptionConversionDelegate() {
|
return new SQLExceptionConversionDelegate() {
|
||||||
@Override
|
@Override
|
||||||
public JDBCException convert(SQLException sqlException, String message, String sql) {
|
public JDBCException convert(SQLException sqlException, String message, String sql) {
|
||||||
|
switch ( sqlException.getErrorCode() ) {
|
||||||
|
case 1205: {
|
||||||
|
return new PessimisticLockException( message, sqlException, sql );
|
||||||
|
}
|
||||||
|
case 1207:
|
||||||
|
case 1206: {
|
||||||
|
return new LockAcquisitionException( message, sqlException, sql );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
|
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
|
||||||
|
|
||||||
if ( "41000".equals( sqlState ) ) {
|
if ( "41000".equals( sqlState ) ) {
|
||||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.internal;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import javax.persistence.EntityExistsException;
|
import javax.persistence.EntityExistsException;
|
||||||
import javax.persistence.EntityNotFoundException;
|
import javax.persistence.EntityNotFoundException;
|
||||||
import javax.persistence.LockTimeoutException;
|
import javax.persistence.LockTimeoutException;
|
||||||
|
@ -34,6 +33,7 @@ import org.hibernate.dialect.lock.OptimisticEntityLockException;
|
||||||
import org.hibernate.dialect.lock.PessimisticEntityLockException;
|
import org.hibernate.dialect.lock.PessimisticEntityLockException;
|
||||||
import org.hibernate.engine.spi.ExceptionConverter;
|
import org.hibernate.engine.spi.ExceptionConverter;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
import org.hibernate.exception.LockAcquisitionException;
|
||||||
import org.hibernate.loader.MultipleBagFetchException;
|
import org.hibernate.loader.MultipleBagFetchException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,12 +89,12 @@ public class ExceptionConverterImpl implements ExceptionConverter {
|
||||||
handlePersistenceException( converted );
|
handlePersistenceException( converted );
|
||||||
return converted;
|
return converted;
|
||||||
}
|
}
|
||||||
else if ( cause instanceof LockingStrategyException ) {
|
else if ( cause instanceof LockAcquisitionException ) {
|
||||||
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
|
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
|
||||||
handlePersistenceException( converted );
|
handlePersistenceException( converted );
|
||||||
return converted;
|
return converted;
|
||||||
}
|
}
|
||||||
else if ( cause instanceof org.hibernate.exception.LockTimeoutException ) {
|
else if ( cause instanceof LockingStrategyException ) {
|
||||||
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
|
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
|
||||||
handlePersistenceException( converted );
|
handlePersistenceException( converted );
|
||||||
return converted;
|
return converted;
|
||||||
|
|
|
@ -69,11 +69,11 @@ public class ForUpdateFragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( upgradeType == LockMode.UPGRADE_NOWAIT ) {
|
if ( upgradeType == LockMode.UPGRADE_NOWAIT || lockOptions.getTimeOut() == LockOptions.NO_WAIT ) {
|
||||||
setNowaitEnabled( true );
|
setNowaitEnabled( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( upgradeType == LockMode.UPGRADE_SKIPLOCKED ) {
|
if ( upgradeType == LockMode.UPGRADE_SKIPLOCKED || lockOptions.getTimeOut() == LockOptions.SKIP_LOCKED ) {
|
||||||
setSkipLockedEnabled( true );
|
setSkipLockedEnabled( true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,8 @@ import javax.persistence.PessimisticLockException;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.dialect.MariaDBDialect;
|
|
||||||
import org.hibernate.dialect.SQLServerDialect;
|
import org.hibernate.dialect.SQLServerDialect;
|
||||||
|
|
||||||
import org.hibernate.testing.SkipForDialect;
|
|
||||||
import org.hibernate.testing.SkipForDialects;
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.jdbc.SQLServerSnapshotIsolationConnectionProvider;
|
import org.hibernate.testing.jdbc.SQLServerSnapshotIsolationConnectionProvider;
|
||||||
import org.hibernate.testing.transaction.TransactionUtil2;
|
import org.hibernate.testing.transaction.TransactionUtil2;
|
||||||
|
@ -31,9 +28,6 @@ import static org.junit.Assert.fail;
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
@SkipForDialects(
|
|
||||||
@SkipForDialect( value = MariaDBDialect.class, jiraKey = "HHH-8786", comment = "https://hibernate.atlassian.net/browse/HHH-8786")
|
|
||||||
)
|
|
||||||
public class LockExceptionTests extends AbstractJPATest {
|
public class LockExceptionTests extends AbstractJPATest {
|
||||||
@Override
|
@Override
|
||||||
public void configure(Configuration cfg) {
|
public void configure(Configuration cfg) {
|
||||||
|
@ -77,6 +71,9 @@ public class LockExceptionTests extends AbstractJPATest {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
finally {
|
finally {
|
||||||
inTransaction(
|
inTransaction(
|
||||||
session -> session.createQuery( "delete Item" ).executeUpdate()
|
session -> session.createQuery( "delete Item" ).executeUpdate()
|
||||||
|
|
Loading…
Reference in New Issue