use of org.hibernate.PessimisticLockException in project hibernate-orm by hibernate.
the class InvalidationTest method testConcurrentRemoveAndPutFromLoad.
@Test
@TestForIssue(jiraKey = "HHH-9868")
public void testConcurrentRemoveAndPutFromLoad() throws Exception {
final Item item = new Item("chris", "Chris's Item");
withTxSession(s -> {
s.persist(item);
});
Phaser deletePhaser = new Phaser(2);
Phaser getPhaser = new Phaser(2);
HookInterceptor hook = new HookInterceptor();
AdvancedCache pendingPutsCache = getPendingPutsCache(Item.class);
pendingPutsCache.addInterceptor(hook, 0);
AtomicBoolean getThreadBlockedInDB = new AtomicBoolean(false);
Thread deleteThread = new Thread(() -> {
try {
withTxSession(s -> {
Item loadedItem = s.get(Item.class, item.getId());
assertNotNull(loadedItem);
arriveAndAwait(deletePhaser, 2000);
arriveAndAwait(deletePhaser, 2000);
log.trace("Item loaded");
s.delete(loadedItem);
s.flush();
log.trace("Item deleted");
arriveAndAwait(deletePhaser, 2000);
arriveAndAwait(deletePhaser, 4000);
});
} catch (Exception e) {
throw new RuntimeException(e);
}
}, "delete-thread");
Thread getThread = new Thread(() -> {
try {
withTxSession(s -> {
Item loadedItem = s.get(Item.class, item.getId());
if (getThreadBlockedInDB.get()) {
assertNull(loadedItem);
} else {
assertNotNull(loadedItem);
}
});
} catch (PessimisticLockException e) {
// (delete-thread has ITEMS table write-locked and we try to acquire read-lock)
try {
arriveAndAwait(getPhaser, 2000);
arriveAndAwait(getPhaser, 2000);
} catch (Exception e1) {
throw new RuntimeException(e1);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}, "get-thread");
deleteThread.start();
// deleteThread loads the entity
arriveAndAwait(deletePhaser, 2000);
withTx(() -> {
sessionFactory().getCache().evictEntity(Item.class, item.getId());
assertFalse(sessionFactory().getCache().containsEntity(Item.class, item.getId()));
return null;
});
arriveAndAwait(deletePhaser, 2000);
// delete thread invalidates PFER
arriveAndAwait(deletePhaser, 2000);
// get thread gets the entity from DB
hook.block(getPhaser, getThread);
getThread.start();
try {
arriveAndAwait(getPhaser, 2000);
} catch (TimeoutException e) {
getThreadBlockedInDB.set(true);
}
arriveAndAwait(deletePhaser, 2000);
// delete thread finishes the remove from DB and cache
deleteThread.join();
hook.unblock();
arriveAndAwait(getPhaser, 2000);
// get thread puts the entry into cache
getThread.join();
assertNoInvalidators(pendingPutsCache);
withTxSession(s -> {
Item loadedItem = s.get(Item.class, item.getId());
assertNull(loadedItem);
});
}
use of org.hibernate.PessimisticLockException in project hibernate-orm by hibernate.
the class SQLStateConversionDelegate method convert.
@Override
public JDBCException convert(SQLException sqlException, String message, String sql) {
final String sqlState = JdbcExceptionHelper.extractSqlState(sqlException);
final int errorCode = JdbcExceptionHelper.extractErrorCode(sqlException);
if (sqlState != null) {
String sqlStateClassCode = JdbcExceptionHelper.determineSqlStateClassCode(sqlState);
if (sqlStateClassCode != null) {
if (SQL_GRAMMAR_CATEGORIES.contains(sqlStateClassCode)) {
return new SQLGrammarException(message, sqlException, sql);
} else if (INTEGRITY_VIOLATION_CATEGORIES.contains(sqlStateClassCode)) {
final String constraintName = getConversionContext().getViolatedConstraintNameExtracter().extractConstraintName(sqlException);
return new ConstraintViolationException(message, sqlException, sql, constraintName);
} else if (CONNECTION_CATEGORIES.contains(sqlStateClassCode)) {
return new JDBCConnectionException(message, sqlException, sql);
} else if (DATA_CATEGORIES.contains(sqlStateClassCode)) {
return new DataException(message, sqlException, sql);
}
}
if ("40001".equals(sqlState)) {
return new LockAcquisitionException(message, sqlException, sql);
}
if ("40XL1".equals(sqlState) || "40XL2".equals(sqlState)) {
// Derby "A lock could not be obtained within the time requested."
return new PessimisticLockException(message, sqlException, sql);
}
// MySQL Query execution was interrupted
if ("70100".equals(sqlState) || // Oracle user requested cancel of current operation
("72000".equals(sqlState) && errorCode == 1013)) {
throw new QueryTimeoutException(message, sqlException, sql);
}
}
return null;
}
use of org.hibernate.PessimisticLockException in project hibernate-orm by hibernate.
the class PostgreSQL81DialectTestCase method testTimeoutException.
@Test
public void testTimeoutException() {
PostgreSQL81Dialect dialect = new PostgreSQL81Dialect();
SQLExceptionConversionDelegate delegate = dialect.buildSQLExceptionConversionDelegate();
assertNotNull(delegate);
JDBCException exception = delegate.convert(new SQLException("Lock Not Available", "55P03"), "", "");
assertTrue(exception instanceof PessimisticLockException);
}
use of org.hibernate.PessimisticLockException in project hibernate-orm by hibernate.
the class VersionedTest method testStaleRead.
protected ByRef<Object> testStaleRead(BiConsumer<Session, Item> consumer) throws Exception {
AtomicReference<Exception> synchronizationException = new AtomicReference<>();
CountDownLatch syncLatch = new CountDownLatch(1);
CountDownLatch commitLatch = new CountDownLatch(1);
Future<Boolean> action = executor.submit(() -> withTxSessionApply(s -> {
try {
((SharedSessionContractImplementor) s).getTransactionCoordinator().getLocalSynchronizations().registerSynchronization(new Synchronization() {
@Override
public void beforeCompletion() {
}
@Override
public void afterCompletion(int i) {
syncLatch.countDown();
try {
awaitOrThrow(commitLatch);
} catch (Exception e) {
synchronizationException.set(e);
}
}
});
Item item = s.load(Item.class, itemId);
consumer.accept(s, item);
s.flush();
} catch (StaleStateException e) {
log.info("Exception thrown: ", e);
markRollbackOnly(s);
return false;
} catch (PessimisticLockException e) {
log.info("Exception thrown: ", e);
markRollbackOnly(s);
return false;
}
return true;
}));
awaitOrThrow(syncLatch);
ByRef<Object> entryRef = new ByRef<>(null);
try {
withTxSession(s -> {
Item item = s.load(Item.class, itemId);
assertEquals("Original item", item.getDescription());
entryRef.set(assertSingleCacheEntry());
});
} finally {
commitLatch.countDown();
}
assertTrue(action.get(WAIT_TIMEOUT, TimeUnit.SECONDS));
assertNull(synchronizationException.get());
return entryRef;
}
Aggregations