session .buildLockRequest( LockOptions.NONE ) .setLockMode( LockMode.PESSIMISTIC_READ ) .setTimeOut( LockOptions.NO_WAIT ) .lock( person ); session .buildLockRequest( LockOptions.NONE ) .setLockMode( LockMode.PESSIMISTIC_READ ) .setTimeOut( LockOptions.NO_WAIT ) .setScope( true ) .lock( person );
session.beginTransaction(); session.buildLockRequest(LockOptions.NONE).lock(hibernatePage);
new LockOptions() .setTimeOut(LockOptions.NO_WAIT)) .setLockMode(LockMode.PESSIMISTIC_WRITE) .lock(_post); }); } finally {
/** * Returns the set of pages that have a link pointing to this page. <b>Warning:</b> Do not use * this for getting the number of inlinks with {@link Page#getInlinks()}.size(). This is too slow. Use * {@link Page#getNumberOfInlinks()} instead. * * @return The set of pages that have a link pointing to this page. */ public Set<Page> getInlinks() { Session session = wiki.__getHibernateSession(); session.beginTransaction(); session.buildLockRequest(LockOptions.NONE).lock(hibernatePage); // Have to copy links here since getPage later will close the session. Set<Integer> pageIDs = new UnmodifiableArraySet<Integer>(hibernatePage.getInLinks()); session.getTransaction().commit(); Set<Page> pages = new HashSet<Page>(); for (int pageID : pageIDs) { try { pages.add(wiki.getPage(pageID)); } catch (WikiApiException e) { // Silently ignore if a page could not be found // There may be inlinks that do not come from an existing page. continue; } } return pages; }
@Test public void testCascadeLockOnDetachedEntityWithScope() { LOGGER.info("Test lock cascade for detached entity with scope"); //Load the Post entity, which will become detached Post post = doInJPA(entityManager -> { return entityManager.createQuery( "select p " + "from Post p " + "join fetch p.details " + "join fetch p.comments " + "where p.id = :id", Post.class) .setParameter("id", 1L) .getSingleResult(); }); doInJPA(entityManager -> { LOGGER.info("Reattach and lock"); entityManager.unwrap(Session.class) .buildLockRequest( new LockOptions(LockMode.PESSIMISTIC_WRITE)) .setScope(true) .lock(post); //The Post entity graph is attached containsPost(entityManager, post, true); }); doInJPA(entityManager -> { //The detached Post entity changes have been lost Post _post = (Post) entityManager.find(Post.class, 1L); assertEquals("Hibernate Master Class", _post.getTitle()); }); }
session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE)).lock(post);
@Test public void testCascadeLockOnDetachedEntityWithScope() { LOGGER.info("Test lock cascade for detached entity with scope"); //Load the Post entity, which will become detached Post post = doInJPA(entityManager -> (Post) entityManager.createQuery( "select p " + "from Post p " + "join fetch p.details " + "join fetch p.comments " + "where p.id = :id", Post.class) .setParameter("id", 1L) .getSingleResult()); doInJPA(entityManager -> { LOGGER.info("Reattach and lock"); entityManager.unwrap(Session.class) .buildLockRequest( new LockOptions(LockMode.PESSIMISTIC_WRITE)) .setScope(true) .lock(post); //The Post entity graph is attached containsPost(entityManager, post, true); }); doInJPA(entityManager -> { //The detached Post entity changes have been lost Post _post = (Post) entityManager.find(Post.class, 1L); assertEquals("Hibernate Master Class", _post.getTitle()); }); }
@Test public void testCascadeLockOnDetachedEntityWithScope() { LOGGER.info("Test lock cascade for detached entity with scope"); //Load the Post entity, which will become detached Post post = doInJPA(entityManager -> (Post) entityManager.createQuery( "select p " + "from Post p " + "join fetch p.details " + "join fetch p.comments " + "where p.id = :id", Post.class) .setParameter("id", 1L) .getSingleResult()); doInJPA(entityManager -> { LOGGER.info("Reattach and lock"); entityManager.unwrap(Session.class) .buildLockRequest( new LockOptions(LockMode.PESSIMISTIC_WRITE)) .setScope(true) .lock(post); //The Post entity graph is attached containsPost(entityManager, post, true); }); doInJPA(entityManager -> { //The detached Post entity changes have been lost Post _post = (Post) entityManager.find(Post.class, 1L); assertEquals("Hibernate Master Class", _post.getTitle()); }); }
/** * Locks an entity (LockMode.NONE) in current hibernate session. * * @param entity * the entity to lock. * @param hibernateSession * the hibernate session. */ private void lockInHibernate(IEntity entity, Session hibernateSession) { if (!hibernateSession.contains(entity)) { // Do not use get before trying to lock. // Get performs a DB query. try { hibernateSession.buildLockRequest(LockOptions.NONE).lock(entity); } catch (NonUniqueObjectException ex) { if (hibernateSession == noTxSession) { hibernateSession.clear(); hibernateSession.buildLockRequest(LockOptions.NONE).lock(entity); } else { throw ex; } } } }
session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE)).lock(post);
session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE)).lock(post);
@Override public void cascade( EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled) { LOG.tracev( "Cascading to lock: {0}", entityName ); LockMode lockMode = LockMode.NONE; LockOptions lr = new LockOptions(); if ( anything instanceof LockOptions ) { LockOptions lockOptions = (LockOptions) anything; lr.setTimeOut( lockOptions.getTimeOut() ); lr.setScope( lockOptions.getScope() ); lr.setFollowOnLocking( lockOptions.getFollowOnLocking() ); if ( lockOptions.getScope() ) { lockMode = lockOptions.getLockMode(); } } lr.setLockMode( lockMode ); session.buildLockRequest( lr ).lock( entityName, child ); }
@Test public void testWithoutMDC() { doInJPA(entityManager -> { Post post = entityManager.createQuery( "select p " + "from Post p " + "where p.id = :id", Post.class) .setParameter("id", 1L) .setLockMode(LockModeType.PESSIMISTIC_WRITE) .getSingleResult(); try { executeSync(() -> { doInJPA(_entityManager -> { Post _post = _entityManager.find(Post.class, 1L); _entityManager.unwrap(Session.class) .buildLockRequest( new LockOptions() .setTimeOut(LockOptions.NO_WAIT)) .setLockMode(LockMode.PESSIMISTIC_WRITE) .lock(_post); }); }); } catch (Exception expected) { assertTrue(ExceptionUtil.rootCause(expected).getMessage().contains("could not obtain lock on row in relation")); } }); }
/** * A strategy method to lock an object with an exclusive lock so that it can * be processed * * @param entity the entity to be locked * @param session * @return true if the entity was locked */ protected boolean lockEntity(Object entity, Session session) { if (!getEndpoint().isConsumeDelete() || !getEndpoint().isConsumeLockEntity()) { return true; } try { if (LOG.isDebugEnabled()) { LOG.debug("Acquiring exclusive lock on entity: " + entity); } session.buildLockRequest(LockOptions.UPGRADE).setLockMode(LockMode.PESSIMISTIC_WRITE).setTimeOut(60000).lock(entity); return true; } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to achieve lock on entity: " + entity + ". Reason: " + e, e); } return false; } }
@Test public void testPessimisticNoWait() { LOGGER.info("Test PESSIMISTIC_READ blocks PESSIMISTIC_WRITE, NO WAIT fails fast"); Post post = doInJPA(entityManager -> { return entityManager.find(Post.class, 1L); }); doInJPA(entityManager -> { entityManager.unwrap( Session.class ).lock(post, LockMode.PESSIMISTIC_WRITE); executeSync( () -> { doInJPA(_entityManager -> { try { _entityManager .unwrap(Session.class) .buildLockRequest( new LockOptions(LockMode.PESSIMISTIC_WRITE) .setTimeOut(LockOptions.NO_WAIT)) .lock(post); fail("Should throw PessimisticEntityLockException"); } catch (PessimisticEntityLockException expected) { //This is expected since the first transaction already acquired this lock } }); } ); }); }
/** * @param journal the Journal * @param acct the account * @param date checkpoint date (inclusive) * @param layers taken into account in this checkpoint * @param threshold minimum number of GLEntries required to create a checkpoint * @throws GLException if user doesn't have CHECKPOINT permission on this journal. */ public void createCheckpoint (Journal journal, Account acct, Date date, int threshold, short[] layers) throws HibernateException, GLException { if (date == null) throw new GLException ("Invalid checkpoint date"); checkPermission (GLPermission.CHECKPOINT, journal); // Transaction tx = session.beginTransaction(); session.buildLockRequest(LockOptions.UPGRADE).lock(journal); createCheckpoint0 (journal, acct, date, threshold, layers); // tx.commit(); } public BigDecimal createBalanceCache
/** REATTACH_BY_LOCK, if hasDirtyCollection then REATTACH_BY_UPDATE */ @Override public <T extends DataObject> T reattach(T obj) { if (isDetached(obj)) { logger.debug("reattaching {}", getObjectShortDesc(obj)); if (obj instanceof CrmProxy) { obj = CrmReflectionUtil.unproxyC(obj); } if (!hasDirtyCollection(obj)) { getCurrentSession().buildLockRequest(LockOptions.NONE).lock(obj); logger.debug(".. fast reattach by lock"); } else { getCurrentSession().update(obj); logger.debug(".. object hasDirtyCollection, so reattach by update"); } resetModDate(obj); } return obj; }
@Override public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled) throws HibernateException { LOG.tracev( "Cascading to lock: {0}", entityName ); LockMode lockMode = LockMode.NONE; LockOptions lr = new LockOptions(); if ( anything instanceof LockOptions) { LockOptions lockOptions = (LockOptions)anything; lr.setTimeOut(lockOptions.getTimeOut()); lr.setScope( lockOptions.getScope()); if ( lockOptions.getScope() == true ) // cascade specified lockMode lockMode = lockOptions.getLockMode(); } lr.setLockMode(lockMode); session.buildLockRequest(lr).lock(entityName, child); } @Override
/** * set a journal's lockDate * @param journal the Journal * @param lockDate the lock date. * @throws HibernateException on database errors. * @throws GLException if users doesn't have global READ permission. */ public void setLockDate (Journal journal, Date lockDate) throws GLException, HibernateException { checkPermission (GLPermission.WRITE, journal); // Transaction tx = session.beginTransaction(); session.buildLockRequest(LockOptions.UPGRADE).lock(journal); journal.setLockDate (lockDate); // tx.commit(); }