blob: 65f3969907490a6cc98f88da09a38fa3a3f844b8 [file] [log] [blame]
/*
* Copyright (c) 2008-2013, 2015, 2016, 2019-2021 Eike Stepper (Loehne, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Simon McDuff - initial API and implementation
* Eike Stepper - maintenance
* Caspar De Groot - write options
*/
package org.eclipse.emf.cdo.tests;
import org.eclipse.emf.cdo.CDOLock;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.lock.CDOLockOwner;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.server.IView;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.session.CDOSessionLocksChangedEvent;
import org.eclipse.emf.cdo.spi.server.InternalLockManager;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.tests.model1.Category;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.tests.model1.Customer;
import org.eclipse.emf.cdo.tests.model1.Product1;
import org.eclipse.emf.cdo.tests.model1.Supplier;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.cdo.util.LockTimeoutException;
import org.eclipse.emf.cdo.util.ObjectNotFoundException;
import org.eclipse.emf.cdo.util.StaleRevisionLockException;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.net4j.signal.ISignalProtocol;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.concurrent.RWOLockManager;
import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
import org.eclipse.net4j.util.event.EventUtil;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.spi.cdo.CDOLockStateCache;
import org.eclipse.emf.spi.cdo.InternalCDOSession;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
import org.eclipse.ocl.util.CollectionUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import junit.framework.AssertionFailedError;
/**
* @author Simon McDuff
*/
public class LockingManagerTest extends AbstractLockingTest
{
public void testAutoReleaseLocks() throws Exception
{
CDOSession session = openSession();
AtomicInteger counter = new AtomicInteger();
try (AutoCloseable listener = EventUtil.addListener(session, CDOSessionLocksChangedEvent.class, event -> counter.incrementAndGet()))
{
CDOTransaction transaction = session.openTransaction();
transaction.options().setAutoReleaseLocksEnabled(false);
CDOResource resource = transaction.createResource(getResourcePath("/test1"));
assertWriteLock(false, resource);
transaction.commit();
assertWriteLock(false, resource);
resource.cdoWriteLock().lock();
assertWriteLock(true, resource);
resource.getContents().add(getModel1Factory().createSupplier());
transaction.commit();
assertWriteLock(true, resource);
resource.cdoWriteLock().unlock();
assertWriteLock(false, resource);
sleep(200);
assertEquals(2, counter.get());
}
}
public void testUnlockAll() throws Exception
{
RWOLockManager<Integer, Integer> lockingManager = new RWOLockManager<>();
Set<Integer> keys = new HashSet<>();
keys.add(1);
keys.add(2);
keys.add(3);
lockingManager.lock(1, keys, LockType.READ, 1, 100, null, null);
lockingManager.unlock(1, (Collection<Integer>)null, (LockType)null, 1, null, null);
}
public void testWriteOptions() throws Exception
{
RWOLockManager<Integer, Integer> lockingManager = new RWOLockManager<>();
Set<Integer> keys = new HashSet<>();
keys.add(1);
lockingManager.lock(1, keys, LockType.OPTION, 1, 100, null, null);
// (R=Read, W=Write, WO=WriteOption)
// Scenario 1: 1 has WO, 2 requests W -> fail
keys.clear();
keys.add(1);
try
{
lockingManager.lock(2, keys, LockType.WRITE, 1, 100, null, null); // Must fail
fail("Should have thrown an exception");
}
catch (TimeoutRuntimeException e)
{
}
// Scenario 2: 1 has WO, 2 requests R -> succeed
try
{
lockingManager.lock(2, keys, LockType.READ, 1, 100, null, null); // Must succeed
}
catch (TimeoutRuntimeException e)
{
fail("Should not have thrown an exception");
}
// Scenario 3: 1 has WO, 2 has R, 1 requests W -> fail
try
{
lockingManager.lock(1, keys, LockType.WRITE, 1, 100, null, null); // Must fail
fail("Should have thrown an exception");
}
catch (TimeoutRuntimeException e)
{
}
// Scenario 4: 1 has WO, 2 has R, 2 requests WO -> fail
try
{
lockingManager.lock(2, keys, LockType.OPTION, 1, 100, null, null); // Must fail
fail("Should have thrown an exception");
}
catch (TimeoutRuntimeException e)
{
}
// Scenario 5: 1 has WO, 2 has nothing, 2 requests WO -> fail
lockingManager.unlock(2, keys, LockType.READ, 1, null, null);
try
{
lockingManager.lock(2, keys, LockType.OPTION, 1, 100, null, null); // Must fail
fail("Should have thrown an exception");
}
catch (TimeoutRuntimeException e)
{
}
// Scenario 6: 1 has W, 2 has nothing, 2 requests WO -> fail
lockingManager.unlock(1, keys, LockType.OPTION, 1, null, null);
lockingManager.lock(1, keys, LockType.WRITE, 1, 100, null, null);
try
{
lockingManager.lock(2, keys, LockType.OPTION, 1, 100, null, null); // Must fail
fail("Should have thrown an exception");
}
catch (TimeoutRuntimeException e)
{
}
// Scenario 7: 1 has W, 1 request WO -> succeed
try
{
lockingManager.lock(1, keys, LockType.OPTION, 1, 100, null, null); // Must succeed
}
catch (TimeoutRuntimeException e)
{
fail("Should not have thrown an exception");
}
// Scenario 8: 1 has W, 2 has R, 1 request WO -> succeed
lockingManager.unlock(1, keys, LockType.OPTION, 1, null, null);
lockingManager.lock(1, keys, LockType.READ, 1, 100, null, null);
try
{
lockingManager.lock(1, keys, LockType.OPTION, 1, 100, null, null); // Must succeed
}
catch (TimeoutRuntimeException e)
{
fail("Should not have thrown an exception");
}
}
public void testBasicUpgradeFromReadToWriteLock() throws Exception
{
RWOLockManager<Integer, Integer> lockingManager = new RWOLockManager<>();
Runnable step1 = new Runnable()
{
@Override
public void run()
{
Set<Integer> keys = new HashSet<>();
keys.add(1);
try
{
lockingManager.lock(1, keys, LockType.WRITE, 1, 50000, null, null);
}
catch (InterruptedException ex)
{
fail("Should not have exception");
}
}
};
ExecutorService executors = getExecutorService();
Set<Integer> keys = new HashSet<>();
keys.add(1);
keys.add(2);
keys.add(3);
keys.add(4);
msg("Context 1 have readlock 1,2,3,4");
lockingManager.lock(1, keys, LockType.READ, 1, 1000, null, null);
assertEquals(true, lockingManager.hasLock(LockType.READ, 1, 1));
assertEquals(true, lockingManager.hasLock(LockType.READ, 1, 2));
assertEquals(true, lockingManager.hasLock(LockType.READ, 1, 3));
assertEquals(true, lockingManager.hasLock(LockType.READ, 1, 4));
keys.clear();
keys.add(1);
keys.add(2);
keys.add(3);
msg("Context 2 have readlock 1,2,3");
lockingManager.lock(2, keys, LockType.READ, 1, 1000, null, null);
assertEquals(true, lockingManager.hasLock(LockType.READ, 2, 1));
assertEquals(true, lockingManager.hasLock(LockType.READ, 2, 2));
assertEquals(true, lockingManager.hasLock(LockType.READ, 2, 3));
assertEquals(true, lockingManager.hasLockByOthers(LockType.READ, 2, 1));
assertEquals(true, lockingManager.hasLockByOthers(LockType.READ, 1, 1));
keys.clear();
keys.add(4);
msg("Context 1 have readlock 1,2,3,4 and writeLock 4");
lockingManager.lock(1, keys, LockType.WRITE, 1, 1000, null, null);
assertEquals(true, lockingManager.hasLock(LockType.READ, 1, 4));
assertEquals(true, lockingManager.hasLock(LockType.WRITE, 1, 4));
keys.clear();
keys.add(1);
try
{
lockingManager.lock(1, keys, LockType.WRITE, 1, 1000, null, null);
fail("Should not have exception");
}
catch (RuntimeException expected)
{
}
executors.execute(step1);
executors.execute(step1);
sleep(1000);
keys.clear();
keys.add(1);
keys.add(2);
keys.add(3);
lockingManager.unlock(2, keys, LockType.READ, 1, null, null);
new PollingTimeOuter()
{
@Override
protected boolean successful()
{
return lockingManager.hasLock(LockType.WRITE, 1, 1);
}
}.assertNoTimeOut();
}
public void testBasicWrongUnlock() throws Exception
{
RWOLockManager<Integer, Integer> lockingManager = new RWOLockManager<>();
Set<Integer> keys = new HashSet<>();
keys.add(1);
lockingManager.lock(1, keys, LockType.READ, 1, 10000, null, null);
lockingManager.unlock(1, keys, LockType.READ, 1, null, null);
// As of 4.4 should not fail anymore.
lockingManager.unlock(1, keys, LockType.READ, 1, null, null);
}
public void testReadTimeout() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
lockWrite(company);
CDOTransaction transaction2 = session.openTransaction();
Company company2 = transaction2.getObject(company);
long start = System.currentTimeMillis();
assertWriteLock(false, company2);
assertEquals(true, System.currentTimeMillis() - start < 300);
start = System.currentTimeMillis();
assertEquals(false, CDOUtil.getCDOObject(company2).cdoWriteLock().tryLock(1000, TimeUnit.MILLISECONDS));
assertEquals(true, System.currentTimeMillis() - start >= 1000);
}
public void testReadLockByOthers() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
lockRead(company);
CDOTransaction transaction2 = session.openTransaction();
Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
new PollingTimeOuter()
{
@Override
protected boolean successful()
{
try
{
CDOObject cdoCompany2 = CDOUtil.getCDOObject(company2);
assertEquals(false, cdoCompany2.cdoWriteLock().isLockedByOthers());
assertEquals(true, cdoCompany2.cdoReadLock().isLockedByOthers());
return true;
}
catch (AssertionFailedError ex)
{
return false;
}
}
}.assertNoTimeOut();
}
public void testDetachedObjects() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
CDOTransaction transaction2 = session.openTransaction();
Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
res.getContents().remove(0);
transaction.commit();
try
{
lockRead(company2);
fail("IllegalArgumentException expected");
}
catch (IllegalArgumentException expected)
{
}
assertReadLock(false, company2);
new PollingTimeOuter()
{
@Override
protected boolean successful()
{
try
{
assertEquals(false, CDOUtil.getCDOObject(company2).cdoReadLock().isLockedByOthers());
return true;
}
catch (AssertionFailedError ex)
{
return false;
}
}
}.assertNoTimeOut();
}
public void testWriteLockByOthers() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
lockWrite(company);
CDOTransaction transaction2 = session.openTransaction();
Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
new PollingTimeOuter()
{
@Override
protected boolean successful()
{
try
{
CDOObject cdoCompany2 = CDOUtil.getCDOObject(company2);
assertEquals(true, cdoCompany2.cdoWriteLock().isLockedByOthers());
assertEquals(false, cdoCompany2.cdoReadLock().isLockedByOthers());
return true;
}
catch (AssertionFailedError ex)
{
return false;
}
}
}.assertNoTimeOut();
}
public void testWriteLock() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
CDOTransaction transaction2 = session.openTransaction();
Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
CDOObject cdoCompany = CDOUtil.getCDOObject(company);
CDOObject cdoCompany2 = CDOUtil.getCDOObject(company2);
transaction.lockObjects(Collections.singletonList(cdoCompany), LockType.WRITE, CDOLock.NO_TIMEOUT);
try
{
transaction2.lockObjects(Collections.singletonList(cdoCompany2), LockType.WRITE, 1000);
fail("LockTimeoutException expected");
}
catch (LockTimeoutException expected)
{
}
company2.setCity("Ottawa");
commitAndTimeout(transaction2);
}
public void _testWriteLock_LongTimeout() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
CDOTransaction transaction2 = session.openTransaction();
Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
CDOObject cdoCompany = CDOUtil.getCDOObject(company);
CDOObject cdoCompany2 = CDOUtil.getCDOObject(company2);
cdoCompany.cdoWriteLock().lock();
IOUtil.OUT().println("Lock acquired by transaction 1");
Thread thread = new Thread()
{
@Override
public void run()
{
try
{
cdoCompany2.cdoWriteLock().lock(3 * ISignalProtocol.DEFAULT_TIMEOUT);
IOUtil.OUT().println("Lock acquired by transaction 2");
company2.setCity("Ottawa");
commitAndSync(transaction2, transaction);
IOUtil.OUT().println("Lock released by transaction 2");
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
};
thread.start();
sleep(2 * ISignalProtocol.DEFAULT_TIMEOUT);
cdoCompany.cdoWriteLock().unlock();
IOUtil.OUT().println("Lock released by transaction 1");
thread.join(DEFAULT_TIMEOUT);
assertEquals("Ottawa", company.getCity());
}
public void testWriteLockViaObject() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
CDOTransaction transaction2 = session.openTransaction();
Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
lockWrite(company);
assertWriteLock(false, company2);
company2.setCity("Ottawa");
commitAndTimeout(transaction2);
}
public void testWriteLockFromDifferenceTransaction() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
CDOTransaction transaction2 = session.openTransaction();
Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
CDOObject cdoCompany = CDOUtil.getCDOObject(company);
CDOObject cdoCompany2 = CDOUtil.getCDOObject(company2);
transaction.lockObjects(Collections.singletonList(cdoCompany), LockType.WRITE, DEFAULT_TIMEOUT);
try
{
transaction2.lockObjects(Collections.singletonList(cdoCompany2), LockType.WRITE, 1000);
fail("LockTimeoutException expected");
}
catch (LockTimeoutException expected)
{
}
}
public void testWriteLockMultiple() throws Exception
{
Company company = getModel1Factory().createCompany();
List<CDOObject> objects = new ArrayList<>();
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
transaction.lockObjects(objects, LockType.WRITE, DEFAULT_TIMEOUT);
assertWriteLock(false, company);
assertReadLock(false, company);
for (CDOObject object : objects)
{
assertWriteLock(true, object);
assertReadLock(false, object);
}
}
public void testWriteUnlockMultiple() throws Exception
{
Company company = getModel1Factory().createCompany();
List<CDOObject> objects = new ArrayList<>();
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
transaction.lockObjects(objects, LockType.WRITE, DEFAULT_TIMEOUT);
assertWriteLock(false, company);
assertReadLock(false, company);
for (CDOObject object : objects)
{
assertWriteLock(true, object);
assertReadLock(false, object);
}
transaction.unlockObjects(objects, LockType.WRITE);
assertWriteLock(false, company);
assertReadLock(false, company);
for (CDOObject object : objects)
{
assertWriteLock(false, object);
assertReadLock(false, object);
}
}
public void testReadLockMultiple() throws Exception
{
Company company = getModel1Factory().createCompany();
List<CDOObject> objects = new ArrayList<>();
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
transaction.lockObjects(objects, LockType.READ, DEFAULT_TIMEOUT);
assertReadLock(false, company);
assertWriteLock(false, company);
for (CDOObject object : objects)
{
assertReadLock(true, object);
assertWriteLock(false, object);
}
}
public void testReadUnlockMultiple() throws Exception
{
Company company = getModel1Factory().createCompany();
List<CDOObject> objects = new ArrayList<>();
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
addCategory(company, objects);
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
transaction.lockObjects(objects, LockType.READ, DEFAULT_TIMEOUT);
assertReadLock(false, company);
assertWriteLock(false, company);
for (CDOObject object : objects)
{
assertReadLock(true, object);
assertWriteLock(false, object);
}
transaction.unlockObjects(objects, LockType.READ);
assertWriteLock(false, company);
assertReadLock(false, company);
for (CDOObject object : objects)
{
assertWriteLock(false, object);
assertReadLock(false, object);
}
}
public void testReadLockAndCommitFromDifferentTransaction() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
CDOTransaction transaction2 = session.openTransaction();
Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
CDOObject cdoCompany = CDOUtil.getCDOObject(company);
transaction.lockObjects(Collections.singletonList(cdoCompany), LockType.READ, DEFAULT_TIMEOUT);
company2.setCity("Ottawa");
commitAndTimeout(transaction2);
}
public void testWriteLockAndCommitFromDifferentTransaction() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
CDOTransaction transaction2 = session.openTransaction();
Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
CDOObject cdoCompany = CDOUtil.getCDOObject(company);
transaction.lockObjects(Collections.singletonList(cdoCompany), LockType.WRITE, DEFAULT_TIMEOUT);
company2.setCity("Ottawa");
commitAndTimeout(transaction2);
}
public void testReadLockAndCommitSameTransaction() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
lockRead(company);
company.setCity("Ottawa");
transaction.commit();
}
public void testWriteLockAndCommitSameTransaction() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
lockWrite(company);
company.setCity("Ottawa");
assertWriteLock(true, company);
assertReadLock(false, company);
transaction.commit();
assertWriteLock(false, company);
assertReadLock(false, company);
}
public void testWriteLockAndRollback() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
lockWrite(company);
company.setCity("Ottawa");
transaction.rollback();
assertWriteLock(false, company);
}
public void testLockUnlock() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
CDOObject cdoCompany = CDOUtil.getCDOObject(company);
lockRead(company);
assertReadLock(true, company);
assertWriteLock(false, company);
lockWrite(company); // Lock upgrade.
assertReadLock(true, company);
assertWriteLock(true, company);
lockRead(company);
assertReadLock(true, company);
assertWriteLock(true, company);
lockWrite(company);
assertReadLock(true, company);
assertWriteLock(true, company);
unlockRead(cdoCompany);
assertReadLock(true, company);
assertWriteLock(true, company);
unlockRead(cdoCompany);
assertReadLock(false, company);
assertWriteLock(true, company);
unlockWrite(cdoCompany);
assertReadLock(false, company);
assertWriteLock(true, company);
unlockWrite(cdoCompany);
assertReadLock(false, company);
assertWriteLock(false, company);
/********************/
lockRead(company);
assertReadLock(true, company);
assertWriteLock(false, company);
lockWrite(company);
assertReadLock(true, company);
assertWriteLock(true, company);
lockRead(company);
assertReadLock(true, company);
assertWriteLock(true, company);
lockWrite(company);
assertReadLock(true, company);
assertWriteLock(true, company);
unlockWrite(cdoCompany);
assertReadLock(true, company);
assertWriteLock(true, company);
unlockWrite(cdoCompany);
assertReadLock(true, company);
assertWriteLock(false, company);
unlockRead(cdoCompany);
assertReadLock(true, company);
assertWriteLock(false, company);
unlockRead(cdoCompany);
assertReadLock(false, company);
assertWriteLock(false, company);
}
/**
* Bug 352191.
*/
public void testLockDetached() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
res.getContents().remove(0);
assertTransient(company);
CDOObject cdoObject = CDOUtil.getCDOObject(company);
transaction.lockObjects(Collections.singleton(cdoObject), LockType.WRITE, DEFAULT_TIMEOUT);
// Verify
CDOTransaction transaction2 = session.openTransaction();
CDOResource res2 = transaction2.getResource(getResourcePath("/res1"));
Company company2 = (Company)res2.getContents().get(0);
company2.setName("NewName");
commitAndTimeout(transaction2);
}
public void testTransactionClose() throws Exception
{
Company company = getModel1Factory().createCompany();
InternalRepository repo = getRepository();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
IView view = repo.getSessionManager().getSession(session.getSessionID()).getView(transaction.getViewID());
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
CDOObject cdoCompany = CDOUtil.getCDOObject(company);
lockRead(company);
transaction.close();
assertEquals(false, repo.getLockingManager().hasLock(LockType.READ, view, cdoCompany.cdoID()));
}
public void testSessionClose() throws Exception
{
Company company = getModel1Factory().createCompany();
InternalRepository repo = getRepository();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
IView view = repo.getSessionManager().getSession(session.getSessionID()).getView(transaction.getViewID());
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
CDOObject cdoCompany = CDOUtil.getCDOObject(company);
lockRead(company);
session.close();
sleep(100);
assertEquals(false, repo.getLockingManager().hasLock(LockType.READ, view, cdoCompany.cdoID()));
}
public void testReadLockedByOthers() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
assertFalse(CDOUtil.getCDOObject(company).cdoReadLock().isLockedByOthers());
transaction.lockObjects(CDOUtil.getCDOObjects(company), LockType.READ, DEFAULT_TIMEOUT);
assertReadLock(true, company);
assertWriteLock(false, company);
assertFalse(CDOUtil.getCDOObject(company).cdoReadLock().isLockedByOthers());
CDOView view = session.openView();
Company viewCompany = view.getObject(company);
assertReadLock(false, viewCompany);
assertWriteLock(false, viewCompany);
assertTrue(CDOUtil.getCDOObject(viewCompany).cdoReadLock().isLockedByOthers());
}
public void testBugzilla_270345() throws Exception
{
Company company1 = getModel1Factory().createCompany();
Company company2 = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction1 = session.openTransaction();
CDOTransaction transaction2 = session.openTransaction();
CDOResource res = transaction1.getOrCreateResource(getResourcePath("/res1"));
res.getContents().add(company1);
res.getContents().add(company2);
transaction1.commit();
lockWrite(company1);
assertWriteLock(true, company1);
Company companyFrom2 = (Company)CDOUtil.getEObject(transaction2.getObject(company2));
companyFrom2.setCity("sss");
transaction2.commit();
assertWriteLock(true, company1);
}
public void testAutoReleaseLockFalse_commit() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
transaction.options().setAutoReleaseLocksEnabled(false);
lockWrite(company);
lockRead(company);
msg("Test with read/write lock");
assertWriteLock(true, company);
assertReadLock(true, company);
company.setCity("Ottawa");
transaction.commit();
assertWriteLock(true, company);
assertReadLock(true, company);
msg("Clean locks");
transaction.unlockObjects(null, null);
msg("Test with read lock");
lockRead(company);
assertReadLock(true, company);
company.setCity("Toronto");
transaction.commit();
assertReadLock(true, company);
transaction.options().setAutoReleaseLocksEnabled(true);
transaction.commit();
assertReadLock(false, company);
}
public void testAutoReleaseLockFalse_rollback() throws Exception
{
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
transaction.options().setAutoReleaseLocksEnabled(false);
lockWrite(company);
lockRead(company);
msg("Test with read/write lock");
assertWriteLock(true, company);
assertReadLock(true, company);
company.setCity("Ottawa");
transaction.rollback();
assertWriteLock(true, company);
assertReadLock(true, company);
msg("Clean locks");
transaction.unlockObjects(null, null);
msg("Test with read lock");
lockRead(company);
assertReadLock(true, company);
company.setCity("Toronto");
transaction.rollback();
assertReadLock(true, company);
transaction.options().setAutoReleaseLocksEnabled(true);
transaction.rollback();
assertReadLock(false, company);
}
public void testWriteLockPerformance() throws Exception
{
int ITERATION = 100;
Company company = getModel1Factory().createCompany();
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
res.getContents().add(company);
transaction.commit();
long start = System.currentTimeMillis();
// 335-418 locks/sec
for (int i = 0; i < ITERATION; i++)
{
lockWrite(company);
}
msg("Lock " + ITERATION / ((double)(System.currentTimeMillis() - start) / 1000) + " objects/sec");
}
public void testReadLockStaleRevision() throws Exception
{
lockStaleRevision(LockType.READ);
}
public void testWriteLockStaleRevision() throws Exception
{
lockStaleRevision(LockType.WRITE);
}
private void lockStaleRevision(LockType type) throws Exception
{
CDOSession session = openSession();
session.options().setPassiveUpdateEnabled(false);
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
Company company = getModel1Factory().createCompany();
company.setName("AAA");
res.getContents().add(company);
transaction.commit();
updateInOtherSession();
try
{
if (type == LockType.WRITE)
{
lockWrite(company);
}
else if (type == LockType.READ)
{
lockRead(company);
}
fail("StaleRevisionLockException expected");
}
catch (StaleRevisionLockException expected)
{
}
session.close();
}
private void updateInOtherSession() throws CommitException
{
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.getResource(getResourcePath("/res1"));
Company company = (Company)res.getContents().get(0);
company.setName("BBB");
transaction.commit();
session.close();
}
private void addCategory(Company company, List<CDOObject> objects)
{
Category category = getModel1Factory().createCategory();
company.getCategories().add(category);
objects.add(CDOUtil.getCDOObject(category));
}
public void testLockContention() throws Exception
{
Company company1 = getModel1Factory().createCompany();
CDOSession session1 = openSession();
CDOTransaction transaction1 = session1.openTransaction();
CDOResource resource1 = transaction1.createResource(getResourcePath("/res1"));
resource1.getContents().add(company1);
transaction1.commit();
lockWrite(company1);
CDOSession session2 = openSession();
CDOTransaction transaction2 = session2.openTransaction();
Company company2 = (Company)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
Throwable[] exception = { null };
Thread client2 = new Thread("Client 2")
{
@Override
public void run()
{
try
{
lockWrite(company2);
assertWriteLock(true, company2);
}
catch (Throwable ex)
{
exception[0] = ex;
}
}
};
client2.start();
sleep(100); // Wait until client2 must have called lock().
unlockWrite(company1); // Unblock client2.
client2.join(DEFAULT_TIMEOUT);
if (exception[0] instanceof Error)
{
throw (Error)exception[0];
}
if (exception[0] instanceof Exception)
{
throw (Exception)exception[0];
}
CDOBranch mainBranch = session2.getBranchManager().getMainBranch();
CDOID id = CDOUtil.getCDOObject(company2).cdoID();
CDOLockStateCache lockStateCache2 = ((InternalCDOSession)session2).getLockStateCache();
CDOLockState lockState = lockStateCache2.getLockState(mainBranch, id);
CDOLockOwner expectedLockOwner = transaction2.getLockOwner();
assertEquals(expectedLockOwner, lockState.getWriteLockOwner());
sleep(200);
assertEquals(expectedLockOwner, lockState.getWriteLockOwner());
}
public void testLockContentionRecursive() throws Exception
{
Company company21 = getModel1Factory().createCompany();
Supplier supplier21 = getModel1Factory().createSupplier();
company21.getSuppliers().add(supplier21);
Customer customer21 = getModel1Factory().createCustomer();
company21.getCustomers().add(customer21);
Category category21 = getModel1Factory().createCategory();
category21.getCategories().add(getModel1Factory().createCategory());
category21.getCategories().add(getModel1Factory().createCategory());
category21.getCategories().add(getModel1Factory().createCategory());
category21.getCategories().add(getModel1Factory().createCategory());
company21.getCategories().add(category21);
CDOSession session2 = openSession();
CDOTransaction transaction21 = session2.openTransaction();
transaction21.options().setLockNotificationEnabled(true);
CDOResource resource21 = transaction21.createResource(getResourcePath("/res1"));
resource21.getContents().add(company21);
transaction21.commit();
@SuppressWarnings("unused")
Set<Object> objects21 = loadView(transaction21);
CDOView view22 = openAndLoadView(session2);
CDOSession session3 = openSession();
CDOTransaction transaction31 = session3.openTransaction();
transaction31.options().setLockNotificationEnabled(true);
Company company31 = (Company)transaction31.getResource(getResourcePath("/res1")).getContents().get(0);
Category category31 = company31.getCategories().get(0);
@SuppressWarnings("unused")
Set<Object> objects31 = loadView(transaction31);
CDOView view32 = openAndLoadView(session3);
System.out.println(transaction21.getLockOwner() + " locking " + category21);
transaction21.lockObjects(CDOUtil.getCDOObjects(category21), LockType.WRITE, DEFAULT_TIMEOUT, true);
assertRecursiveWriteLock(transaction21.getLockOwner(), category21);
sleep(500); // Wait until all other views must have been notified.
assertRecursiveWriteLock(transaction21.getLockOwner(), view22.getObject(category21));
assertRecursiveWriteLock(transaction21.getLockOwner(), category31);
assertRecursiveWriteLock(transaction21.getLockOwner(), view32.getObject(category31));
Throwable[] exception = { null };
Thread client3 = new Thread("Client 3")
{
@Override
public void run()
{
try
{
System.out.println(transaction21.getLockOwner() + " locking " + company31);
transaction31.lockObjects(CDOUtil.getCDOObjects(company31), LockType.WRITE, DEFAULT_TIMEOUT, true);
assertRecursiveWriteLock(transaction31.getLockOwner(), company31);
sleep(500); // Wait until all other views must have been notified.
assertRecursiveWriteLock(transaction31.getLockOwner(), view32.getObject(company31));
assertRecursiveWriteLock(transaction31.getLockOwner(), company21);
assertRecursiveWriteLock(transaction31.getLockOwner(), view22.getObject(company21));
}
catch (Throwable ex)
{
exception[0] = ex;
}
}
};
client3.start();
sleep(100); // Wait until client3 must have called lock().
// Unblock client3.
System.out.println(transaction21.getLockOwner() + " unlocking " + category21);
transaction21.unlockObjects(CDOUtil.getCDOObjects(category21), LockType.WRITE, true);
client3.join(DEFAULT_TIMEOUT);
if (exception[0] instanceof Error)
{
throw (Error)exception[0];
}
if (exception[0] instanceof Exception)
{
throw (Exception)exception[0];
}
}
private static CDOView openAndLoadView(CDOSession session)
{
CDOView view = session.openView();
view.options().setLockNotificationEnabled(true);
Set<Object> objects = loadView(view);
view.properties().put("objects", objects);
return view;
}
private static Set<Object> loadView(CDOView view)
{
Set<Object> objects = new HashSet<>();
CDOResource rootResource = view.getRootResource();
objects.add(rootResource);
for (Iterator<?> it = rootResource.eAllContents(); it.hasNext();)
{
objects.add(it.next());
}
return objects;
}
protected static void assertRecursiveWriteLock(CDOLockOwner owner, EObject object)
{
CDOObject cdoObject = CDOUtil.getCDOObject(object);
CDOLockOwner objectLockOwner = cdoObject.cdoView().getLockOwner();
assertRecursiveWriteLock(owner, objectLockOwner, cdoObject);
for (Iterator<?> it = cdoObject.eAllContents(); it.hasNext();)
{
CDOObject o = CDOUtil.getCDOObject((EObject)it.next());
assertRecursiveWriteLock(owner, objectLockOwner, o);
}
}
private static void assertRecursiveWriteLock(CDOLockOwner owner, CDOLockOwner objectLockOwner, CDOObject cdoObject)
{
CDOLock lock = cdoObject.cdoWriteLock();
assertEquals("owner of " + cdoObject, owner, CollectionUtil.first(lock.getOwners()));
if (objectLockOwner == owner)
{
assertEquals("isLocked of " + cdoObject, true, lock.isLocked());
}
else
{
assertEquals("isLockedByOthers of " + cdoObject, true, lock.isLockedByOthers());
}
}
public void testRecursiveLock() throws Exception
{
CDOSession session = openSession();
session.options().setPassiveUpdateEnabled(false);
CDOTransaction transaction = session.openTransaction();
CDOResource res = transaction.createResource(getResourcePath("/res1"));
Category category1 = getModel1Factory().createCategory();
Category category2_1 = getModel1Factory().createCategory();
Category category2_2 = getModel1Factory().createCategory();
Category category3 = getModel1Factory().createCategory();
res.getContents().add(category1);
category1.getCategories().add(category2_1);
category1.getCategories().add(category2_2);
category2_1.getCategories().add(category3);
transaction.commit();
CDOObject top = CDOUtil.getCDOObject(category1);
transaction.lockObjects(Collections.singleton(top), LockType.WRITE, 5000, true);
assertWriteLock(true, category1);
assertWriteLock(true, category2_1);
assertWriteLock(true, category2_2);
assertWriteLock(true, category3);
transaction.unlockObjects(Collections.singleton(top), LockType.WRITE, true);
assertWriteLock(false, category1);
assertWriteLock(false, category2_1);
assertWriteLock(false, category2_2);
assertWriteLock(false, category3);
session.close();
}
public void testLockOnNewObject() throws Exception
{
CDOSession session = openSession();
CDOSession controlSession = openSession();
CDOTransaction transaction = session.openTransaction();
transaction.options().setAutoReleaseLocksEnabled(false);
CDOResource resource = transaction.createResource(getResourcePath("/res1"));
transaction.commit();
Category category1 = getModel1Factory().createCategory();
Category category2 = getModel1Factory().createCategory();
Category category3 = getModel1Factory().createCategory();
resource.getContents().add(category1);
resource.getContents().add(category2);
resource.getContents().add(category3);
lockRead(category1);
lockWrite(category2);
lockOption(category3);
assertReadLock(true, category1);
assertWriteLock(true, category2);
assertOptionLock(true, category3);
unlockRead(category1);
unlockWrite(category2);
unlockOption(category3);
assertReadLock(false, category1);
assertWriteLock(false, category2);
assertOptionLock(false, category3);
lockRead(category1);
lockWrite(category2);
lockOption(category3);
transaction.commit();
// Verify that locks on new objects are properly cached now.
assertReadLock(true, category1);
assertWriteLock(true, category2);
assertOptionLock(true, category3);
// Test lock visibility in different view.
CDOView controlView = controlSession.openView();
controlView.options().setLockNotificationEnabled(true);
CDOResource resourceCV = controlView.getResource(getResourcePath("/res1"));
CDOObject category1CV = CDOUtil.getCDOObject(resourceCV.getContents().get(0));
CDOObject category2CV = CDOUtil.getCDOObject(resourceCV.getContents().get(1));
CDOObject category3CV = CDOUtil.getCDOObject(resourceCV.getContents().get(2));
new PollingTimeOuter()
{
@Override
protected boolean successful()
{
try
{
assertEquals(true, category1CV.cdoReadLock().isLockedByOthers());
assertEquals(true, category2CV.cdoWriteLock().isLockedByOthers());
assertEquals(true, category3CV.cdoWriteOption().isLockedByOthers());
return true;
}
catch (AssertionFailedError ex)
{
return false;
}
}
}.assertNoTimeOut();
unlockRead(category1);
unlockWrite(category2);
unlockOption(category3);
new PollingTimeOuter()
{
@Override
protected boolean successful()
{
try
{
assertEquals(false, category1CV.cdoReadLock().isLockedByOthers());
assertEquals(false, category2CV.cdoReadLock().isLockedByOthers());
assertEquals(false, category3CV.cdoReadLock().isLockedByOthers());
return true;
}
catch (AssertionFailedError ex)
{
return false;
}
}
}.assertNoTimeOut();
session.close();
controlSession.close();
}
public void testDeleteLockedObject() throws Exception
{
CDOSession session1 = openSession();
CDOSession session2 = openSession();
CDOTransaction tx = session1.openTransaction();
tx.options().setAutoReleaseLocksEnabled(false);
CDOResource resource = tx.createResource(getResourcePath("/res1"));
Category category1 = getModel1Factory().createCategory();
resource.getContents().add(category1);
tx.commit();
CDOID id = CDOUtil.getCDOObject(category1).cdoID();
lockWrite(category1);
resource.getContents().remove(category1);
tx.commit();
CDOView controlView = session2.openView();
try
{
controlView.getObject(id);
fail("Should have thrown " + ObjectNotFoundException.class.getSimpleName());
}
catch (ObjectNotFoundException ignore)
{
// Do nothing
}
InternalLockManager mgr = getRepository().getLockingManager();
boolean branching = getRepository().isSupportingBranches();
Object key = branching ? CDOIDUtil.createIDAndBranch(id, tx.getBranch()) : id;
LockState<Object, IView> state = mgr.getLockState(key);
assertNull(state);
}
public void testAutoReleaseLocksOnUnchangedObject() throws Exception
{
Company company = getModel1Factory().createCompany();
Category category1 = getModel1Factory().createCategory();
company.getCategories().add(category1);
Category category2 = getModel1Factory().createCategory();
company.getCategories().add(category2);
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/res1"));
resource.getContents().add(company);
transaction.commit();
CDOLock writeLock = CDOUtil.getCDOObject(category1).cdoWriteLock();
writeLock.lock(DEFAULT_TIMEOUT);
// Check that explicit lock on unchanged object is not released
transaction.options().setAutoReleaseLocksEnabled(false);
category2.setName("NewName");
transaction.commit();
assertEquals(true, writeLock.isLocked()); // Explicit lock not released because of AutoReleaseLocks=false
assertEquals(false, CDOUtil.getCDOObject(category2).cdoWriteLock().isLocked()); // Implicit locks always released
// Check that explicit lock on unchanged object is released
transaction.options().setAutoReleaseLocksEnabled(true);
category2.setName("NewName2");
transaction.commit();
assertEquals(false, writeLock.isLocked()); // Explicit lock released because of AutoReleaseLocks=true
assertEquals(false, CDOUtil.getCDOObject(category2).cdoWriteLock().isLocked()); // Implicit locks always released
}
public void testAutoReleaseReadLockWithLockedByOthers() throws Exception
{
Category category1 = getModel1Factory().createCategory();
CDOSession session1 = openSession();
CDOTransaction transaction1 = session1.openTransaction();
transaction1.options().setLockNotificationEnabled(true);
CDOResource resource1 = transaction1.createResource(getResourcePath("/res1"));
resource1.getContents().add(category1);
transaction1.commit();
CDOSession session2 = openSession();
CDOTransaction transaction2 = session2.openTransaction();
Category category2 = (Category)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
lockRead(category2);
CDOLock readLock1 = lockRead(category1);
new PollingTimeOuter()
{
@Override
protected boolean successful()
{
return readLock1.isLockedByOthers();
}
}.assertNoTimeOut();
resource1.getContents().add(getModel1Factory().createProduct1());
transaction1.commit();
assertEquals(true, readLock1.isLockedByOthers());
}
public void testAutoReleaseWriteLockWithLockedByOthers() throws Exception
{
Category category1 = getModel1Factory().createCategory();
Product1 product1 = getModel1Factory().createProduct1();
CDOSession session1 = openSession();
CDOTransaction transaction1 = session1.openTransaction();
transaction1.options().setLockNotificationEnabled(true);
CDOResource resource1 = transaction1.createResource(getResourcePath("/res1"));
resource1.getContents().add(category1);
resource1.getContents().add(product1);
transaction1.commit();
CDOSession session2 = openSession();
InternalCDOTransaction transaction2 = (InternalCDOTransaction)session2.openTransaction();
Category category2 = (Category)transaction2.getResource(getResourcePath("/res1")).getContents().get(0);
lockWrite(product1);
lockWrite(category2);
CDOLock otherWriteLock1 = CDOUtil.getCDOObject(category1).cdoWriteLock();
new PollingTimeOuter()
{
@Override
protected boolean successful()
{
return otherWriteLock1.isLockedByOthers();
}
}.assertNoTimeOut();
product1.setName("NewName");
transaction1.commit();
assertEquals(true, otherWriteLock1.isLockedByOthers());
}
public void testAutoReleaseExplicitLocks() throws Exception
{
Company company = getModel1Factory().createCompany();
Category category1 = getModel1Factory().createCategory();
company.getCategories().add(category1);
Category category2 = getModel1Factory().createCategory();
company.getCategories().add(category2);
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
CDOResource resource = transaction.createResource(getResourcePath("/res1"));
resource.getContents().add(company);
transaction.commit();
CDOLock writeLock = CDOUtil.getCDOObject(category1).cdoWriteLock();
writeLock.lock(DEFAULT_TIMEOUT);
// Check that explicit lock on changed object is not released
transaction.options().setAutoReleaseLocksEnabled(false);
category1.setName("NewName");
transaction.commit();
assertEquals(true, writeLock.isLocked());
// Check that explicit lock on changed object is released
transaction.options().setAutoReleaseLocksEnabled(true);
category1.setName("NewName2");
transaction.commit();
assertEquals(false, writeLock.isLocked());
}
public void testLockRefreshForHeldLock() throws Exception
{
// Client 1 creates and read-locks a resource.
CDOSession session1 = openSession();
CDOTransaction tx1 = session1.openTransaction();
CDOResource resource1 = tx1.createResource(getResourcePath("/res1"));
tx1.commit();
resource1.cdoReadLock().lock();
// Client 2 loads the resource created and read-locked by Client 1.
CDOSession session2 = openSession();
CDOTransaction tx2 = session2.openTransaction();
CDOResource resource2 = tx2.getResource(getResourcePath("/res1"));
// Client 2 gets the lock and locks it.
CDOLock readLockBeforeClose = resource2.cdoReadLock();
readLockBeforeClose.lock(DEFAULT_TIMEOUT);
boolean isLockedByOthersBeforeClose = readLockBeforeClose.isLockedByOthers();
assertTrue(isLockedByOthersBeforeClose);
tx1.close(); // Client 1 releases its read lock.
new PollingTimeOuter()
{
@Override
protected boolean successful()
{
CDOLock readLockAfterClose = resource2.cdoReadLock();
boolean isLockedByOthersAfterClose = readLockAfterClose.isLockedByOthers();
return isLockedByOthersAfterClose == false;
}
}.assertNoTimeOut();
}
public void testRefreshLockStates() throws Exception
{
// Client 1 creates and read-locks a resource.
CDOTransaction tx1 = openSession().openTransaction();
CDOResource resource1 = tx1.createResource(getResourcePath("/res1"));
tx1.commit();
resource1.cdoReadLock().lock();
// Client 2 gets the resource created and read-locked by Client 1.
CDOTransaction tx2 = openSession().openTransaction();
CDOResource resource2 = tx2.getResource(getResourcePath("/res1"));
// Get the lock and DON'T lock it.
CDOLock readLockBeforeClose = resource2.cdoReadLock();
boolean isLockedByOthersBeforeClose = readLockBeforeClose.isLockedByOthers();
assertTrue(isLockedByOthersBeforeClose);
tx1.close(); // Client 1 release read lock.
tx2.refreshLockStates(null);
CDOLock readLockAfterClose = resource2.cdoReadLock();
boolean isLockedByOthersAfterClose = readLockAfterClose.isLockedByOthers();
assertTrue(isLockedByOthersAfterClose);
}
private void commitAndTimeout(CDOTransaction transaction)
{
InternalRepository repository = getRepository();
long oldTimeout = repository.getOptimisticLockingTimeout();
repository.setOptimisticLockingTimeout(1000);
try
{
transaction.commit();
fail("CommitException expected");
}
catch (CommitException expected)
{
// SUCCESS
}
finally
{
repository.setOptimisticLockingTimeout(oldTimeout);
}
}
}