HHH-8786 - find, refresh, lock should throw LockTimeoutException or PessimisticLockException when lock problems occur

This commit is contained in:
Steve Ebersole 2018-04-27 08:32:22 -05:00
parent 12b79a5938
commit 676aebdf51
1 changed files with 162 additions and 0 deletions

View File

@ -0,0 +1,162 @@
/*
* 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.test.jpa.lock;
import java.util.Collections;
import javax.persistence.LockModeType;
import javax.persistence.LockTimeoutException;
import javax.persistence.PessimisticLockException;
import org.hibernate.LockOptions;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.jdbc.SQLServerSnapshotIsolationConnectionProvider;
import org.hibernate.testing.transaction.TransactionUtil2;
import org.hibernate.test.jpa.AbstractJPATest;
import org.hibernate.test.jpa.Item;
import org.junit.Test;
import static org.junit.Assert.fail;
/**
* @author Steve Ebersole
*/
public class LockExceptionTests extends AbstractJPATest {
@Override
public void configure(Configuration cfg) {
super.configure( cfg );
if( SQLServerDialect.class.isAssignableFrom( DIALECT.getClass() )) {
cfg.getProperties().put( AvailableSettings.CONNECTION_PROVIDER, new SQLServerSnapshotIsolationConnectionProvider() );
}
}
@Test
@TestForIssue( jiraKey = "HHH-8786" )
public void testLockTimeoutFind() {
final Item item = new Item( "find" );
inTransaction(
session -> session.persist( item )
);
try {
inTransaction(
session -> {
session.find( Item.class, item.getId(), LockModeType.PESSIMISTIC_WRITE );
TransactionUtil2.inTransaction(
sessionFactory(),
secondSession -> {
try {
secondSession.find(
Item.class,
item.getId(),
LockModeType.PESSIMISTIC_WRITE,
Collections.singletonMap( AvailableSettings.JPA_LOCK_TIMEOUT, LockOptions.NO_WAIT )
);
fail( "Expecting a failure" );
}
catch ( LockTimeoutException | PessimisticLockException expected ) {
// expected outcome
}
}
);
}
);
}
finally {
inTransaction(
session -> session.createQuery( "delete Item" ).executeUpdate()
);
}
}
@Test
public void testLockTimeoutRefresh() {
final Item item = new Item( "refresh" );
inTransaction(
session -> session.persist( item )
);
try {
inTransaction(
session -> {
session.find( Item.class, item.getId(), LockModeType.PESSIMISTIC_WRITE );
TransactionUtil2.inTransaction(
sessionFactory(),
secondSession -> {
try {
// generally speaking we should be able to read the row
Item item2 = secondSession.get( Item.class, item.getId() );
secondSession.refresh(
item2,
LockModeType.PESSIMISTIC_WRITE,
Collections.singletonMap( AvailableSettings.JPA_LOCK_TIMEOUT, LockOptions.NO_WAIT )
);
fail( "Expecting a failure" );
}
catch ( LockTimeoutException | PessimisticLockException expected ) {
// expected outcome
}
}
);
}
);
}
finally {
inTransaction(
session -> session.createQuery( "delete Item" ).executeUpdate()
);
}
}
@Test
public void testLockTimeoutLock() {
final Item item = new Item( "lock" );
inTransaction(
session -> session.persist( item )
);
try {
inTransaction(
session -> {
session.find( Item.class, item.getId(), LockModeType.PESSIMISTIC_WRITE );
TransactionUtil2.inTransaction(
sessionFactory(),
secondSession -> {
try {
// generally speaking we should be able to read the row
Item item2 = secondSession.get( Item.class, item.getId() );
secondSession.lock(
item2,
LockModeType.PESSIMISTIC_WRITE,
Collections.singletonMap( AvailableSettings.JPA_LOCK_TIMEOUT, LockOptions.NO_WAIT )
);
fail( "Expecting a failure" );
}
catch ( LockTimeoutException | PessimisticLockException expected ) {
// expected outcome
}
}
);
}
);
}
finally {
inTransaction(
session -> session.createQuery( "delete Item" ).executeUpdate()
);
}
}
}