| /* |
| * Copyright (c) 2011, 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.simultaneous; |
| |
| |
| import org.eclipse.persistence.internal.identitymaps.CacheKey; |
| import org.eclipse.persistence.internal.sessions.AbstractSession; |
| import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl; |
| import org.eclipse.persistence.sessions.Session; |
| import org.eclipse.persistence.sessions.UnitOfWork; |
| import org.eclipse.persistence.testing.framework.AutoVerifyTestCase; |
| import org.eclipse.persistence.testing.models.employee.domain.Employee; |
| import org.eclipse.persistence.testing.models.employee.domain.Project; |
| import org.eclipse.persistence.testing.models.employee.domain.SmallProject; |
| |
| import org.eclipse.persistence.testing.models.employee.domain.Address; |
| |
| //see bug 305611 |
| |
| public class AppendLockTest extends AutoVerifyTestCase { |
| |
| Employee emp = null; |
| SmallProject project = null; |
| Address address = null; |
| |
| public AppendLockTest() { |
| super(); |
| } |
| |
| |
| @Override |
| protected void setup() throws Throwable { |
| super.setup(); |
| getExecutor().swapServerSession(); |
| UnitOfWork uow = getSession().acquireUnitOfWork(); |
| project = new SmallProject(); |
| uow.registerNewObject(project); |
| emp = new Employee(); |
| address = new Address(); |
| uow.registerNewObject(address); |
| uow.registerNewObject(emp); |
| uow.commit(); |
| } |
| |
| @Override |
| protected void test() throws Throwable { |
| // TODO Auto-generated method stub |
| super.test(); |
| Thread locker = new Thread(new Locker(getSession(), address)); |
| Thread writer1 = new Thread(new Writer1(getSession(), emp, project, address)); |
| Thread writer2 = new Thread (new Writer2(getSession(), project)); |
| locker.start(); |
| writer1.start(); |
| writer2.start(); |
| writer2.join(60000); |
| try{ |
| if (writer2.isAlive()){ |
| try{ |
| writer2.interrupt(); |
| writer1.interrupt(); |
| locker.interrupt(); |
| }catch (Exception e) { |
| } |
| fail("Bug 9484687 - deadlock occured."); |
| } |
| |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| @Override |
| public void reset() throws Throwable { |
| super.reset(); |
| getExecutor().resetSession(); |
| getSession().getIdentityMapAccessor().initializeAllIdentityMaps(); |
| UnitOfWork uow = getSession().acquireUnitOfWork(); |
| this.project = (SmallProject) uow.refreshObject(project); |
| this.emp = (Employee)uow.refreshObject(emp); |
| uow.deleteObject(project); |
| uow.deleteObject(emp); |
| uow.commit(); |
| } |
| |
| public static class Writer1 implements Runnable{ |
| protected Project project; |
| protected Employee emp; |
| protected Session session; |
| protected Address address; |
| |
| public Writer1(Session session, Employee emp, Project project, Address address){ |
| this.session = session; |
| this.project = project; |
| this.emp = emp; |
| this.address =address; |
| } |
| |
| @Override |
| public void run() { |
| UnitOfWork uow = session.acquireUnitOfWork(); |
| Project p = (Project) uow.readObject(project); |
| Address address = (Address) uow.readObject(this.address); |
| Employee emp = (Employee) uow.readObject(this.emp); |
| emp.setAddress(address); |
| p.setDescription("SomeBigLongDescription"); |
| ((AbstractSession)this.session).getIdentityMapAccessorInstance().getCacheKeyForObject(this.project).setObject(null); |
| ((UnitOfWorkImpl)uow).getCloneToOriginals().remove(p); |
| synchronized (this.session) { |
| try { |
| this.session.notifyAll(); |
| this.session.wait(20000); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| } |
| uow.commit(); |
| synchronized (this.session) { |
| this.session.notifyAll(); |
| } |
| } |
| |
| } |
| |
| public static class Locker implements Runnable{ |
| protected Address address; |
| protected Session session; |
| |
| public Locker(Session session, Address address){ |
| this.session = session; |
| this.address = address; |
| } |
| |
| @Override |
| public void run() { |
| CacheKey cacheKey = null; |
| synchronized (this.session) { |
| try { |
| this.session.wait(20000); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| } |
| try{ |
| cacheKey = ((AbstractSession)this.session).getIdentityMapAccessorInstance().acquireLock(this.address.getId(), this.address.getClass(), this.session.getClassDescriptor(this.address), false); |
| synchronized (this.session) { |
| this.session.notifyAll(); |
| try { |
| this.session.wait(5000); |
| } catch (InterruptedException e) { |
| //TODO Auto-generated catch block |
| e.printStackTrace(); |
| } |
| } |
| }finally{ |
| cacheKey.release(); |
| } |
| } |
| |
| } |
| |
| public static class Writer2 implements Runnable{ |
| protected Session session; |
| protected Project project; |
| |
| |
| public Writer2(Session session, Project project){ |
| this.session = session; |
| this.project = project; |
| } |
| |
| @Override |
| public void run() { |
| synchronized (this.session) { |
| try { |
| this.session.wait(20000); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| } |
| synchronized (this.session) { |
| try { |
| this.session.wait(20000); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| } |
| synchronized (this.session) { |
| try { |
| this.session.wait(20000); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| } |
| UnitOfWork uow = this.session.acquireUnitOfWork(); |
| try{ |
| this.project = (Project) uow.refreshObject(this.project); // should block |
| |
| synchronized (this.session) { |
| this.session.notifyAll(); |
| } |
| uow.release(); |
| }catch(Exception ex){ |
| System.out.println("Thread was interrupted"); |
| } |
| } |
| |
| } |
| |
| } |