"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "hsqldb/src/org/hsqldb/TransactionManagerCommon.java" between
hsqldb-2.7.1.zip and hsqldb-2.7.2.zip

About: HSQLDB (HyperSQL DataBase) is a SQL relational database engine written in Java. It supports nearly full ANSI-92 SQL (BNF format) and full core SQL:2008.

TransactionManagerCommon.java  (hsqldb-2.7.1):TransactionManagerCommon.java  (hsqldb-2.7.2)
/* Copyright (c) 2001-2022, The HSQL Development Group /* Copyright (c) 2001-2023, The HSQL Development Group
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* Redistributions of source code must retain the above copyright notice, this * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above copyright notice, * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
skipping to change at line 45 skipping to change at line 45
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.hsqldb.HsqlNameManager.HsqlName; import org.hsqldb.HsqlNameManager.HsqlName;
import org.hsqldb.error.Error; import org.hsqldb.error.Error;
import org.hsqldb.error.ErrorCode; import org.hsqldb.error.ErrorCode;
import org.hsqldb.lib.ArrayUtil; import org.hsqldb.lib.ArrayUtil;
import org.hsqldb.lib.HashMap; import org.hsqldb.lib.HashMap;
import org.hsqldb.lib.HsqlArrayList; import org.hsqldb.lib.HsqlArrayList;
import org.hsqldb.lib.Iterator; import org.hsqldb.lib.Iterator;
import org.hsqldb.lib.LongDeque; import org.hsqldb.lib.LongDeque;
import org.hsqldb.lib.LongKeyHashMap;
import org.hsqldb.lib.MultiValueHashMap; import org.hsqldb.lib.MultiValueHashMap;
import org.hsqldb.lib.OrderedHashSet; import org.hsqldb.lib.OrderedHashSet;
/** /**
* Shared code for TransactionManager classes * Shared code for TransactionManager classes
* *
* @author Fred Toussi (fredt@users dot sourceforge.net) * @author Fred Toussi (fredt@users dot sourceforge.net)
* @version 2.7.1 * @version 2.7.2
* @since 2.0.0 * @since 2.0.0
*/ */
class TransactionManagerCommon { class TransactionManagerCommon {
Database database; Database database;
Session lobSession; Session lobSession;
int txModel; int txModel;
HsqlName[] catalogNameList; HsqlName[] catalogNameList;
// //
skipping to change at line 82 skipping to change at line 81
/** global timestamp for database */ /** global timestamp for database */
AtomicLong systemChangeNumber = new AtomicLong(1); AtomicLong systemChangeNumber = new AtomicLong(1);
// //
AtomicInteger transactionCount = new AtomicInteger(); AtomicInteger transactionCount = new AtomicInteger();
// //
HashMap tableWriteLocks = new HashMap(); HashMap tableWriteLocks = new HashMap();
MultiValueHashMap tableReadLocks = new MultiValueHashMap(); MultiValueHashMap tableReadLocks = new MultiValueHashMap();
// /**
* Normally false. When SET DATABASE TRANSACTION CONTROL is used to change
* the transaction control model, the old instance of TransactionManager
* is set as expired.
*/
volatile boolean hasExpired; volatile boolean hasExpired;
// functional unit - cached table transactions
/** Map : rowID maps to: RowAction */
public LongKeyHashMap rowActionMap;
TransactionManagerCommon(Database database) { TransactionManagerCommon(Database database) {
this.database = database; this.database = database;
catalogNameList = new HsqlName[]{ database.getCatalogName() }; catalogNameList = new HsqlName[]{ database.getCatalogName() };
} }
void setTransactionControl(Session session, int mode) { void setTransactionControl(Session session, int mode) {
TransactionManagerCommon manager = null; TransactionManagerCommon manager = null;
if (mode == txModel) { if (mode == txModel) {
skipping to change at line 183 skipping to change at line 181
manager.systemChangeNumber.set(systemChangeNumber.get()); manager.systemChangeNumber.set(systemChangeNumber.get());
manager.transactionCount = transactionCount; manager.transactionCount = transactionCount;
hasExpired = true; hasExpired = true;
database.txManager = (TransactionManager) manager; database.txManager = (TransactionManager) manager;
} finally { } finally {
writeLock.unlock(); writeLock.unlock();
} }
} }
void beginTransactionCommon(Session session) { final void beginTransactionCommon(Session session) {
session.actionSCN = getNextSystemChangeNumber(); session.actionSCN = getNextSystemChangeNumber();
session.actionStartSCN = session.actionSCN; session.actionStartSCN = session.actionSCN;
session.transactionSCN = session.actionSCN; session.transactionSCN = session.actionSCN;
session.isPreTransaction = false; session.isPreTransaction = false;
session.isTransaction = true; session.isTransaction = true;
transactionCount.incrementAndGet(); transactionCount.incrementAndGet();
} }
void adjustLobUsage(Session session) { final void adjustLobUsage(Session session) {
int limit = session.rowActionList.size(); int limit = session.rowActionList.size();
long lastActionTimestamp = session.actionSCN; long lastActionTimestamp = session.actionSCN;
for (int i = 0; i < limit; i++) { for (int i = 0; i < limit; i++) {
RowAction action = (RowAction) session.rowActionList.get(i); RowAction action = (RowAction) session.rowActionList.get(i);
if (action.type == RowActionBase.ACTION_NONE) { if (action.type == RowActionBase.ACTION_NONE) {
continue; continue;
} }
skipping to change at line 243 skipping to change at line 241
if (newLimit > limit) { if (newLimit > limit) {
for (int i = limit; i < newLimit; i++) { for (int i = limit; i < newLimit; i++) {
RowAction lobAction = (RowAction) session.rowActionList.get(i); RowAction lobAction = (RowAction) session.rowActionList.get(i);
lobAction.commit(session); lobAction.commit(session);
} }
} }
} }
Statement updateCurrentStatement(Session session, Statement cs) { final Statement updateCurrentStatement(Session session, Statement cs) {
if (cs.getCompileTimestamp() if (cs.getCompileTimestamp()
< database.schemaManager.getSchemaChangeTimestamp()) { < database.schemaManager.getSchemaChangeTimestamp()) {
cs = session.statementManager.getStatement(cs); cs = session.statementManager.getStatement(cs);
session.sessionContext.currentStatement = cs;
if (cs == null) {
session.sessionContext.invalidStatement = true;
} else {
session.sessionContext.currentStatement = cs;
}
} }
return cs; return cs;
} }
void persistCommit(Session session) { final void persistCommit(Session session) {
int limit = session.rowActionList.size(); int limit = session.rowActionList.size();
boolean writeCommit = false; boolean writeCommit = false;
for (int i = 0; i < limit; i++) { for (int i = 0; i < limit; i++) {
RowAction action = (RowAction) session.rowActionList.get(i); RowAction action = (RowAction) session.rowActionList.get(i);
if (action.type == RowActionBase.ACTION_NONE) { if (action.type == RowActionBase.ACTION_NONE) {
continue; continue;
} }
skipping to change at line 302 skipping to change at line 305
session.logSequences(); session.logSequences();
if (limit > 0 && writeCommit) { if (limit > 0 && writeCommit) {
database.logger.writeCommitStatement(session); database.logger.writeCommitStatement(session);
} }
} catch (HsqlException e) { } catch (HsqlException e) {
database.logger.logWarningEvent("data commit logging failed", e); database.logger.logWarningEvent("data commit logging failed", e);
} }
} }
void finaliseRows(Session session, Object[] list, int start, int limit) { final void finaliseRows(Session session, Object[] list, int start, int limit ) {
for (int i = start; i < limit; i++) { for (int i = start; i < limit; i++) {
RowAction action = (RowAction) list[i]; RowAction action = (RowAction) list[i];
action.store.postCommitAction(session, action); action.store.postCommitAction(session, action);
} }
} }
/** /**
* merge a transaction committed at a given timestamp. * merge a transaction committed at a given timestamp.
*/ */
void mergeTransaction(Object[] list, int start, int limit, final void mergeTransaction(Object[] list, int start, int limit,
long timestamp) { long timestamp) {
for (int i = start; i < limit; i++) { for (int i = start; i < limit; i++) {
RowAction rowact = (RowAction) list[i]; RowAction rowact = (RowAction) list[i];
rowact.mergeToTimestamp(timestamp); rowact.mergeToTimestamp(timestamp);
} }
} }
/** /**
* gets the next timestamp for an action * gets the next timestamp for an action
*/ */
public long getNextSystemChangeNumber() { public final long getNextSystemChangeNumber() {
return systemChangeNumber.incrementAndGet(); return systemChangeNumber.incrementAndGet();
} }
boolean checkDeadlock(Session session, OrderedHashSet newWaits) { final static boolean checkDeadlock(Session session, OrderedHashSet newWaits) {
int size = session.waitingSessions.size(); int size = session.waitingSessions.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Session current = (Session) session.waitingSessions.get(i); Session current = (Session) session.waitingSessions.get(i);
if (newWaits.contains(current)) { if (newWaits.contains(current)) {
return false; return false;
} }
if (!checkDeadlock(current, newWaits)) { if (!checkDeadlock(current, newWaits)) {
return false; return false;
} }
} }
return true; return true;
} }
boolean checkDeadlock(Session session, Session other) { final boolean checkDeadlock(Session session, Session other) {
int size = session.waitingSessions.size(); int size = session.waitingSessions.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Session current = (Session) session.waitingSessions.get(i); Session current = (Session) session.waitingSessions.get(i);
if (current == other) { if (current == other) {
return false; return false;
} }
if (!checkDeadlock(current, other)) { if (!checkDeadlock(current, other)) {
return false; return false;
} }
} }
return true; return true;
} }
void getTransactionSessions(Session session) { final void getTransactionSessions(Session session) {
OrderedHashSet set = session.tempSet; OrderedHashSet set = session.tempSet;
Session[] sessions = database.sessionManager.getAllSessions(); Session[] sessions = database.sessionManager.getAllSessions();
for (int i = 0; i < sessions.length; i++) { for (int i = 0; i < sessions.length; i++) {
long timestamp = sessions[i].transactionSCN; long timestamp = sessions[i].transactionSCN;
if (session != sessions[i] && sessions[i].isTransaction) { if (session != sessions[i] && sessions[i].isTransaction) {
set.add(sessions[i]); set.add(sessions[i]);
} }
} }
} }
void getTransactionAndPreSessions(Session session) { final void getTransactionAndPreSessions(Session session) {
OrderedHashSet set = session.tempSet; OrderedHashSet set = session.tempSet;
Session[] sessions = database.sessionManager.getAllSessions(); Session[] sessions = database.sessionManager.getAllSessions();
for (int i = 0; i < sessions.length; i++) { set.clear();
long timestamp = sessions[i].transactionSCN;
for (int i = 0; i < sessions.length; i++) {
if (session == sessions[i]) { if (session == sessions[i]) {
continue; continue;
} }
if (sessions[i].isPreTransaction) { if (sessions[i].isPreTransaction) {
set.add(sessions[i]); set.add(sessions[i]);
} else if (sessions[i].isTransaction) { } else if (sessions[i].isTransaction) {
set.add(sessions[i]); set.add(sessions[i]);
} }
} }
} }
void endActionTPL(Session session) { final void endActionTPL(Session session) {
if (session.isolationLevel == SessionInterface.TX_REPEATABLE_READ if (session.isolationLevel == SessionInterface.TX_REPEATABLE_READ
|| session.isolationLevel || session.isolationLevel
== SessionInterface.TX_SERIALIZABLE) { == SessionInterface.TX_SERIALIZABLE) {
return; return;
} }
if (session.sessionContext.currentStatement == null) { if (session.sessionContext.invalidStatement) {
// after java function / proc with db access
return; return;
} }
if (session.sessionContext.depth > 0) { if (session.sessionContext.depth > 0) {
// routine or trigger // routine or trigger
return; return;
} }
HsqlName[] readLocks = HsqlName[] readLocks =
skipping to change at line 470 skipping to change at line 471
if (current.abortTransaction) { if (current.abortTransaction) {
canUnlock = true; canUnlock = true;
break; break;
} }
Statement currentStatement = Statement currentStatement =
current.sessionContext.currentStatement; current.sessionContext.currentStatement;
if (currentStatement == null) { if (current.sessionContext.invalidStatement) {
canUnlock = true; canUnlock = true;
break; break;
} }
if (ArrayUtil.containsAny( if (ArrayUtil.containsAny(
readLocks, currentStatement.getTableNamesForWrite())) { readLocks, currentStatement.getTableNamesForWrite())) {
canUnlock = true; canUnlock = true;
break; break;
skipping to change at line 509 skipping to change at line 510
final int waitingCount = session.waitingSessions.size(); final int waitingCount = session.waitingSessions.size();
if (waitingCount == 0) { if (waitingCount == 0) {
return; return;
} }
resetLocks(session); resetLocks(session);
resetLatches(session); resetLatches(session);
} }
void resetLocks(Session session) { final void resetLocks(Session session) {
final int waitingCount = session.waitingSessions.size(); final int waitingCount = session.waitingSessions.size();
for (int i = 0; i < waitingCount; i++) { for (int i = 0; i < waitingCount; i++) {
Session current = (Session) session.waitingSessions.get(i); Session current = (Session) session.waitingSessions.get(i);
current.tempUnlocked = false; current.tempUnlocked = false;
long count = current.latch.getCount(); long count = current.latch.getCount();
skipping to change at line 553 skipping to change at line 554
// //
} else { } else {
// this can introduce additional waits for the sessions // this can introduce additional waits for the sessions
setWaitedSessionsTPL(current, setWaitedSessionsTPL(current,
current.sessionContext.currentStatement); current.sessionContext.currentStatement);
} }
} }
} }
void resetLatches(Session session) { final void resetLatches(Session session) {
final int waitingCount = session.waitingSessions.size(); final int waitingCount = session.waitingSessions.size();
for (int i = 0; i < waitingCount; i++) { for (int i = 0; i < waitingCount; i++) {
Session current = (Session) session.waitingSessions.get(i); Session current = (Session) session.waitingSessions.get(i);
boolean monitorCode = false; boolean monitorCode = false;
if (monitorCode) { if (monitorCode) {
if (!current.abortTransaction && current.tempSet.isEmpty()) { if (!current.abortTransaction && current.tempSet.isEmpty()) {
skipping to change at line 586 skipping to change at line 587
} }
} }
setWaitingSessionTPL(current); setWaitingSessionTPL(current);
} }
session.waitingSessions.clear(); session.waitingSessions.clear();
session.latch.setCount(0); session.latch.setCount(0);
} }
void resetLatchesMidTransaction(Session session) { final void resetLatchesMidTransaction(Session session) {
session.tempSet.clear(); session.tempSet.clear();
session.tempSet.addAll(session.waitingSessions); session.tempSet.addAll(session.waitingSessions);
session.waitingSessions.clear(); session.waitingSessions.clear();
final int waitingCount = session.tempSet.size(); final int waitingCount = session.tempSet.size();
for (int i = 0; i < waitingCount; i++) { for (int i = 0; i < waitingCount; i++) {
Session current = (Session) session.tempSet.get(i); Session current = (Session) session.tempSet.get(i);
boolean monitorCode = false; boolean monitorCode = false;
skipping to change at line 622 skipping to change at line 623
} }
} }
} }
setWaitingSessionTPL(current); setWaitingSessionTPL(current);
} }
session.tempSet.clear(); session.tempSet.clear();
} }
boolean setWaitedSessionsTPL(Session session, Statement cs) { final boolean setWaitedSessionsTPL(Session session, Statement cs) {
session.tempSet.clear(); session.tempSet.clear();
if (cs == null) { if (cs == null) {
return true; return true;
} }
if (session.abortTransaction) { if (session.abortTransaction) {
return false; return false;
} }
skipping to change at line 701 skipping to change at line 702
return true; return true;
} }
session.tempSet.clear(); session.tempSet.clear();
session.abortTransaction = true; session.abortTransaction = true;
return false; return false;
} }
void setWaitingSessionTPL(Session session) { final void setWaitingSessionTPL(Session session) {
int count = session.tempSet.size(); int count = session.tempSet.size();
int latchCount = session.latch.getCount(); int latchCount = session.latch.getCount();
if (latchCount > count + 1) { if (latchCount > count + 1) {
System.out.println("latch count " + latchCount); System.out.println("latch count " + latchCount);
} }
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
Session current = (Session) session.tempSet.get(i); Session current = (Session) session.tempSet.get(i);
current.waitingSessions.add(session); current.waitingSessions.add(session);
} }
session.tempSet.clear(); session.tempSet.clear();
session.latch.setCount(count); session.latch.setCount(count);
} }
void lockTablesTPL(Session session, Statement cs) { final void lockTablesTPL(Session session, Statement cs) {
if (cs == null || session.abortTransaction) { if (cs == null || session.abortTransaction) {
return; return;
} }
HsqlName[] nameList = cs.getTableNamesForWrite(); HsqlName[] nameList = cs.getTableNamesForWrite();
for (int i = 0; i < nameList.length; i++) { for (int i = 0; i < nameList.length; i++) {
HsqlName name = nameList[i]; HsqlName name = nameList[i];
skipping to change at line 757 skipping to change at line 758
HsqlName name = nameList[i]; HsqlName name = nameList[i];
if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) { if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
continue; continue;
} }
tableReadLocks.put(name, session); tableReadLocks.put(name, session);
} }
} }
void unlockTablesTPL(Session session) { final void unlockTablesTPL(Session session) {
Iterator it = tableWriteLocks.values().iterator(); Iterator it = tableWriteLocks.values().iterator();
while (it.hasNext()) { while (it.hasNext()) {
Session s = (Session) it.next(); Session s = (Session) it.next();
if (s == session) { if (s == session) {
it.remove(); it.remove();
} }
} }
skipping to change at line 780 skipping to change at line 781
while (it.hasNext()) { while (it.hasNext()) {
Session s = (Session) it.next(); Session s = (Session) it.next();
if (s == session) { if (s == session) {
it.remove(); it.remove();
} }
} }
} }
void unlockReadTablesTPL(Session session, HsqlName[] locks) { final void unlockReadTablesTPL(Session session, HsqlName[] locks) {
for (int i = 0; i < locks.length; i++) { for (int i = 0; i < locks.length; i++) {
tableReadLocks.remove(locks[i], session); tableReadLocks.remove(locks[i], session);
} }
} }
boolean hasLocks(Session session, Statement cs) { final boolean hasLocks(Session session, Statement cs) {
if (cs == null) { if (cs == null) {
return true; return true;
} }
HsqlName[] nameList = cs.getTableNamesForWrite(); HsqlName[] nameList = cs.getTableNamesForWrite();
for (int i = 0; i < nameList.length; i++) { for (int i = 0; i < nameList.length; i++) {
HsqlName name = nameList[i]; HsqlName name = nameList[i];
skipping to change at line 838 skipping to change at line 839
Session holder = (Session) tableWriteLocks.get(name); Session holder = (Session) tableWriteLocks.get(name);
if (holder != null && holder != session) { if (holder != null && holder != session) {
return false; return false;
} }
} }
return true; return true;
} }
long getFirstLiveTransactionTimestamp() { final long getFirstLiveTransactionTimestamp() {
if (liveTransactionSCNs.isEmpty()) { if (liveTransactionSCNs.isEmpty()) {
return Long.MAX_VALUE; return Long.MAX_VALUE;
} }
return liveTransactionSCNs.get(0); return liveTransactionSCNs.get(0);
} }
/** /**
* Return an array of all row actions sorted by System Change No. * Return an array of all row actions sorted by System Change No.
*/ */
RowAction[] getRowActionList() { final RowAction[] getRowActionList() {
writeLock.lock(); writeLock.lock();
try { try {
Session[] sessions = database.sessionManager.getAllSessions(); Session[] sessions = database.sessionManager.getAllSessions();
int[] tIndex = new int[sessions.length]; int[] tIndex = new int[sessions.length];
RowAction[] rowActions; RowAction[] rowActions;
int rowActionCount = 0; int rowActionCount = 0;
{ {
skipping to change at line 1011 skipping to change at line 1012
targetSession.rollbackNoCheck(true); targetSession.rollbackNoCheck(true);
targetSession.close(); targetSession.close();
} }
break; break;
} }
} finally { } finally {
writeLock.unlock(); writeLock.unlock();
} }
} }
void prepareReset(Session session) { final void prepareReset(Session session) {
OrderedHashSet waitedSessions = session.waitedSessions; OrderedHashSet waitedSessions = session.waitedSessions;
for (int i = 0; i < waitedSessions.size(); i++) { for (int i = 0; i < waitedSessions.size(); i++) {
Session current = (Session) waitedSessions.get(i); Session current = (Session) waitedSessions.get(i);
current.waitingSessions.remove(session); current.waitingSessions.remove(session);
} }
waitedSessions.clear(); waitedSessions.clear();
 End of changes. 34 change blocks. 
40 lines changed or deleted 41 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)