blob: 3e7485480831a6cdee9c63eb85da907d82227eec [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.internal.cache;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import org.apache.geode.annotations.internal.MakeNotStatic;
import org.apache.geode.cache.CommitConflictException;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.internal.cache.locks.TXLockId;
import org.apache.geode.internal.cache.locks.TXLockService;
import org.apache.geode.internal.cache.locks.TXRegionLockRequest;
/**
* TXLockRequest represents all the locks that need to be made for a single transaction.
*
*
* @since GemFire 4.0
*
*/
public class TXLockRequest {
private boolean localLockHeld;
private TXLockId distLockId;
private IdentityArrayList localLocks; // of TXRegionLockRequest
private ArrayList<TXRegionLockRequest> distLocks; // of TXRegionLockRequest
private Set otherMembers;
public TXLockRequest() {
this.localLockHeld = false;
this.distLockId = null;
this.localLocks = null;
this.distLocks = null;
this.otherMembers = null;
}
void setOtherMembers(Set s) {
this.otherMembers = s;
}
public void addLocalRequest(TXRegionLockRequest req) {
if (this.localLocks == null) {
this.localLocks = new IdentityArrayList();
}
this.localLocks.add(req);
}
public TXRegionLockRequest getRegionLockRequest(String regionFullPath) {
if (this.localLocks == null || regionFullPath == null) {
return null;
}
Iterator<TXRegionLockRequestImpl> it = this.localLocks.iterator();
while (it.hasNext()) {
TXRegionLockRequestImpl rlr = it.next();
if (rlr.getRegionFullPath().equals(regionFullPath)) {
return rlr;
}
}
return null;
}
void addDistributedRequest(TXRegionLockRequest req) {
if (this.distLocks == null) {
this.distLocks = new ArrayList<TXRegionLockRequest>();
}
this.distLocks.add(req);
}
public void obtain(InternalDistributedSystem system) throws CommitConflictException {
if (this.localLocks != null && !this.localLocks.isEmpty()) {
txLocalLock(this.localLocks);
this.localLockHeld = true;
}
if (this.distLocks != null && !this.distLocks.isEmpty()) {
this.distLockId = TXLockService.createDTLS(system).txLock(this.distLocks, this.otherMembers);
}
}
/**
* Release any local locks obtained by this request
*/
public void releaseLocal() {
if (this.localLockHeld) {
txLocalRelease(this.localLocks);
this.localLockHeld = false;
}
}
/**
* Release any distributed locks obtained by this request
*/
public void releaseDistributed(InternalDistributedSystem system) {
if (this.distLockId != null) {
try {
TXLockService txls = TXLockService.createDTLS(system);
txls.release(this.distLockId);
} catch (IllegalStateException ignore) {
// IllegalStateException: TXLockService cannot be created
// until connected to distributed system
// could be thrown if a jvm is disconnected from the ds,
// and tries to createDTLS() during clean up
}
this.distLockId = null;
}
}
public TXLockId getDistributedLockId() {
return this.distLockId;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getCanonicalName()).append("@").append(System.identityHashCode(this));
sb.append(" RegionLockRequests:");
if (this.localLocks != null) {
Iterator it = this.localLocks.iterator();
while (it.hasNext()) {
TXRegionLockRequest rlr = (TXRegionLockRequest) it.next();
sb.append(" TXRegionLockRequest:");
sb.append(rlr.getRegionFullPath()).append(" keys:").append(rlr.getKeys());
}
}
return sb.toString();
}
public void cleanup(InternalDistributedSystem system) {
releaseLocal();
releaseDistributed(system);
}
@MakeNotStatic
private static final TXReservationMgr resMgr = new TXReservationMgr(true);
/**
* @param localLocks is a list of TXRegionLockRequest instances
*/
private static void txLocalLock(IdentityArrayList localLocks) throws CommitConflictException {
resMgr.makeReservation(localLocks);
}
private static void txLocalRelease(IdentityArrayList localLocks) {
resMgr.releaseReservation(localLocks);
}
}