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'
|
||||
],
|
||||
mariadb : [
|
||||
'db.dialect' : 'org.hibernate.dialect.MariaDB102Dialect',
|
||||
'db.dialect' : '',
|
||||
// 'db.dialect' : 'org.hibernate.dialect.MariaDB102Dialect',
|
||||
'jdbc.driver': 'org.mariadb.jdbc.Driver',
|
||||
'jdbc.user' : 'hibernate_orm_test',
|
||||
'jdbc.pass' : 'hibernate_orm_test',
|
||||
|
|
|
@ -207,6 +207,7 @@ tasks.withType( Test.class ).all { task ->
|
|||
}
|
||||
|
||||
processTestResources {
|
||||
inputs.property( "db", db )
|
||||
doLast {
|
||||
copy {
|
||||
from( sourceSets.test.java.srcDirs ) {
|
||||
|
|
|
@ -7,11 +7,12 @@
|
|||
package org.hibernate.dialect;
|
||||
|
||||
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||
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
|
||||
*/
|
||||
|
@ -58,4 +59,27 @@ public class MariaDB103Dialect extends MariaDB102Dialect {
|
|||
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.NullPrecedence;
|
||||
import org.hibernate.PessimisticLockException;
|
||||
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.function.NoArgSQLFunction;
|
||||
|
@ -525,6 +526,16 @@ public class MySQLDialect extends Dialect {
|
|||
return new SQLExceptionConversionDelegate() {
|
||||
@Override
|
||||
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 );
|
||||
|
||||
if ( "41000".equals( sqlState ) ) {
|
||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.internal;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.persistence.EntityExistsException;
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
import javax.persistence.LockTimeoutException;
|
||||
|
@ -34,6 +33,7 @@ import org.hibernate.dialect.lock.OptimisticEntityLockException;
|
|||
import org.hibernate.dialect.lock.PessimisticEntityLockException;
|
||||
import org.hibernate.engine.spi.ExceptionConverter;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.exception.LockAcquisitionException;
|
||||
import org.hibernate.loader.MultipleBagFetchException;
|
||||
|
||||
/**
|
||||
|
@ -89,12 +89,12 @@ public class ExceptionConverterImpl implements ExceptionConverter {
|
|||
handlePersistenceException( converted );
|
||||
return converted;
|
||||
}
|
||||
else if ( cause instanceof LockingStrategyException ) {
|
||||
else if ( cause instanceof LockAcquisitionException ) {
|
||||
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
|
||||
handlePersistenceException( converted );
|
||||
return converted;
|
||||
}
|
||||
else if ( cause instanceof org.hibernate.exception.LockTimeoutException ) {
|
||||
else if ( cause instanceof LockingStrategyException ) {
|
||||
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
|
||||
handlePersistenceException( 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 );
|
||||
}
|
||||
|
||||
if ( upgradeType == LockMode.UPGRADE_SKIPLOCKED ) {
|
||||
if ( upgradeType == LockMode.UPGRADE_SKIPLOCKED || lockOptions.getTimeOut() == LockOptions.SKIP_LOCKED ) {
|
||||
setSkipLockedEnabled( true );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,11 +14,8 @@ import javax.persistence.PessimisticLockException;
|
|||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.dialect.MariaDBDialect;
|
||||
import org.hibernate.dialect.SQLServerDialect;
|
||||
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.SkipForDialects;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.jdbc.SQLServerSnapshotIsolationConnectionProvider;
|
||||
import org.hibernate.testing.transaction.TransactionUtil2;
|
||||
|
@ -31,9 +28,6 @@ import static org.junit.Assert.fail;
|
|||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SkipForDialects(
|
||||
@SkipForDialect( value = MariaDBDialect.class, jiraKey = "HHH-8786", comment = "https://hibernate.atlassian.net/browse/HHH-8786")
|
||||
)
|
||||
public class LockExceptionTests extends AbstractJPATest {
|
||||
@Override
|
||||
public void configure(Configuration cfg) {
|
||||
|
@ -77,6 +71,9 @@ public class LockExceptionTests extends AbstractJPATest {
|
|||
}
|
||||
);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
inTransaction(
|
||||
session -> session.createQuery( "delete Item" ).executeUpdate()
|
||||
|
|
Loading…
Reference in New Issue