blob: 7854c340cd45044b46da323ce388f3aee80ca4a2 [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.unitofwork;
import java.math.BigDecimal;
import org.eclipse.persistence.sessions.UnitOfWork;
import org.eclipse.persistence.testing.framework.TestCase;
import org.eclipse.persistence.testing.framework.TestErrorException;
import org.eclipse.persistence.testing.framework.TestWarningException;
public class ConcurrentReadOnUpdateWithEarlyTransTest extends TestCase {
// used as monitor for test
public static ConcurrentAddress readAddress;
public ConcurrentAddress originalReference;
public ConcurrentAddress readObject;
//used in remote unit of work tests to control when the lock is released
public static int whosWaiting;
public static final int READER = 2;
public static final int WRITER = 1;
public static ThreadLocal threadId = new ThreadLocal();
public ConcurrentReadOnUpdateWithEarlyTransTest() {
}
@Override
public void setup() {
// The purpose of this test is to test multi-threaded server execution,
// remote is for a single client, so this test is not relevant.
if (getSession().isDistributedSession()) {
throw new TestWarningException("Test unavailable on Remote UnitOfWork.");
}
readAddress = new ConcurrentAddress();
readAddress.setId(new BigDecimal(8));
readAddress.setCity("Toronto");
readAddress.setPostalCode("L5J2B5");
readAddress.setProvince("ONT");
readAddress.setStreet("1450 Acme Cr., suite 4");
readAddress.setCountry("Canada");
UnitOfWork uow = getSession().acquireUnitOfWork();
uow.registerObject(readAddress);
uow.commit();
ConcurrentAddress.RUNNING_TEST = ConcurrentAddress.READ_ON_UPDATE_EARLY_TRANS;
getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
}
@Override
public void test() {
UnitOfWork uow = getSession().acquireUnitOfWork();
ConcurrentPerson person = (ConcurrentPerson)uow.readObject(ConcurrentPerson.class);
originalReference = person.getAddress();
uow.beginEarlyTransaction();
ConcurrentAddress addressClone =
(ConcurrentAddress)uow.readObject(ConcurrentReadOnUpdateWithEarlyTransTest.readAddress);
person.setAddress(addressClone);
//begin multi threading
Thread loadThread = new Thread(this.runnable());
loadThread.start();
threadId.set("Writer");
try {
//let the reader start
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
uow.commit();
try {
loadThread.join();
} catch (InterruptedException ex) {
}
}
public Runnable runnable() {
return new Runnable() {
@Override
public void run() {
threadId.set("Reader");
synchronized (ConcurrentReadOnUpdateWithEarlyTransTest.readAddress) {
ConcurrentReadOnUpdateWithEarlyTransTest.whosWaiting =
ConcurrentReadOnUpdateWithEarlyTransTest.READER;
try {
ConcurrentReadOnUpdateWithEarlyTransTest.readAddress.wait(30000);
} catch (InterruptedException ex) {
}
}
readObject =
(ConcurrentAddress)getSession().readObject(ConcurrentReadOnUpdateWithEarlyTransTest.readAddress);
synchronized (ConcurrentReadOnUpdateWithEarlyTransTest.readAddress) {
ConcurrentReadOnUpdateWithEarlyTransTest.readAddress.notifyAll(); //wake writer
}
}
};
}
@Override
public void verify() {
ConcurrentPerson person = (ConcurrentPerson)getSession().readObject(ConcurrentPerson.class);
if (person.getAddress() != readObject) {
throw new TestErrorException("Object Identity Lost during merge");
}
}
@Override
public void reset() {
ConcurrentAddress.RUNNING_TEST = ConcurrentAddress.NONE;
try {
UnitOfWork unitOfWork = getSession().acquireUnitOfWork();
((ConcurrentPerson)unitOfWork.readObject(ConcurrentPerson.class)).setAddress((ConcurrentAddress)unitOfWork.registerObject(originalReference));
unitOfWork.deleteObject(ConcurrentReadOnUpdateWithEarlyTransTest.readAddress);
unitOfWork.commit();
} finally {
ConcurrentReadOnInsertTest.readAddress = null;
}
getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
}
}