📄 xactfactory.java
字号:
/* Derby - Class org.apache.derby.impl.store.raw.xact.XactFactory Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable. Licensed 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.derby.impl.store.raw.xact;import org.apache.derby.iapi.reference.Property;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.services.context.ContextService;import org.apache.derby.iapi.services.context.ContextManager;import org.apache.derby.iapi.services.daemon.DaemonService;import org.apache.derby.iapi.services.daemon.Serviceable;import org.apache.derby.iapi.services.locks.LockFactory;import org.apache.derby.iapi.services.monitor.ModuleControl;import org.apache.derby.iapi.services.monitor.ModuleSupportable;import org.apache.derby.iapi.services.monitor.Monitor;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.services.io.Formatable;import org.apache.derby.iapi.services.io.FormatIdUtil;import org.apache.derby.iapi.services.uuid.UUIDFactory;import org.apache.derby.catalog.UUID;import org.apache.derby.iapi.store.access.AccessFactoryGlobals;import org.apache.derby.iapi.store.access.TransactionController;import org.apache.derby.iapi.store.access.TransactionInfo;import org.apache.derby.iapi.store.access.AccessFactory;import org.apache.derby.iapi.store.access.xa.XAResourceManager;import org.apache.derby.iapi.store.raw.LockingPolicy;import org.apache.derby.iapi.store.raw.GlobalTransactionId;import org.apache.derby.iapi.store.raw.RawStoreFactory;import org.apache.derby.iapi.store.raw.Transaction;import org.apache.derby.iapi.store.raw.data.DataFactory;import org.apache.derby.iapi.store.raw.log.LogFactory;import org.apache.derby.iapi.store.raw.log.LogInstant;import org.apache.derby.iapi.store.raw.xact.TransactionFactory;import org.apache.derby.iapi.store.raw.xact.RawTransaction;import org.apache.derby.iapi.store.raw.xact.TransactionId;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.impl.store.raw.xact.XactXAResourceManager;import java.util.Enumeration;import java.util.Properties;import java.util.Hashtable;public class XactFactory implements TransactionFactory, ModuleControl, ModuleSupportable{ protected static final String USER_CONTEXT_ID = "UserTransaction"; protected static final String NESTED_READONLY_USER_CONTEXT_ID = "NestedRawReadOnlyUserTransaction"; protected static final String NESTED_UPDATE_USER_CONTEXT_ID = "NestedRawUpdateUserTransaction"; protected static final String INTERNAL_CONTEXT_ID = "InternalTransaction"; protected static final String NTT_CONTEXT_ID = "NestedTransaction"; /* ** Fields */ protected DaemonService rawStoreDaemon; private UUIDFactory uuidFactory; protected ContextService contextFactory; protected LockFactory lockFactory; protected LogFactory logFactory; protected DataFactory dataFactory; protected RawStoreFactory rawStoreFactory; public TransactionTable ttab; private long tranId; private LockingPolicy[][] lockingPolicies = new LockingPolicy[3][6]; private boolean inCreateNoLog = false; // creating database, no logging private XAResourceManager xa_resource; /* ** Constructor */ public XactFactory() { super(); } /* ** Methods of ModuleControl */ public boolean canSupport(Properties startParams) { return true; } public void boot(boolean create, Properties properties) throws StandardException { uuidFactory = Monitor.getMonitor().getUUIDFactory(); contextFactory = ContextService.getFactory(); lockFactory = (LockFactory) Monitor.bootServiceModule(false, this, org.apache.derby.iapi.reference.Module.LockFactory, properties); // adding entries to locking policy table which means we support that // level of concurrency. lockingPolicies[LockingPolicy.MODE_NONE] [TransactionController.ISOLATION_NOLOCK] = new NoLocking(); lockingPolicies[LockingPolicy.MODE_RECORD] [TransactionController.ISOLATION_NOLOCK] = new NoLocking(); lockingPolicies[LockingPolicy.MODE_RECORD] [TransactionController.ISOLATION_READ_UNCOMMITTED] = new RowLocking1(lockFactory); lockingPolicies[LockingPolicy.MODE_RECORD] [TransactionController.ISOLATION_READ_COMMITTED] = new RowLocking2(lockFactory); lockingPolicies[LockingPolicy.MODE_RECORD] [TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK] = new RowLocking2nohold(lockFactory); lockingPolicies[LockingPolicy.MODE_RECORD] [TransactionController.ISOLATION_REPEATABLE_READ] = new RowLockingRR(lockFactory); lockingPolicies[LockingPolicy.MODE_RECORD] [TransactionController.ISOLATION_SERIALIZABLE] = new RowLocking3(lockFactory); lockingPolicies[LockingPolicy.MODE_CONTAINER] [TransactionController.ISOLATION_NOLOCK] = new NoLocking(); // note that current implementation of read uncommitted still gets // container and container intent locks to prevent concurrent ddl. Thus // the read uncommitted containerlocking implementation is the same as // the read committed implementation. Future customer requests may // force us to change this - we will then have to figure out how to // handle a table being dropped while a read uncommitted scanner is // reading it - currently we just block that from happening. lockingPolicies[LockingPolicy.MODE_CONTAINER] [TransactionController.ISOLATION_READ_UNCOMMITTED] = new ContainerLocking2(lockFactory); lockingPolicies[LockingPolicy.MODE_CONTAINER] [TransactionController.ISOLATION_READ_COMMITTED] = new ContainerLocking2(lockFactory); lockingPolicies[LockingPolicy.MODE_CONTAINER] [TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK] = new ContainerLocking2(lockFactory); lockingPolicies[LockingPolicy.MODE_CONTAINER] [TransactionController.ISOLATION_REPEATABLE_READ] = new ContainerLocking3(lockFactory); lockingPolicies[LockingPolicy.MODE_CONTAINER] [TransactionController.ISOLATION_SERIALIZABLE] = new ContainerLocking3(lockFactory); if (create) { ttab = new TransactionTable(); String noLog = properties.getProperty(Property.CREATE_WITH_NO_LOG); inCreateNoLog = (noLog != null && Boolean.valueOf(noLog).booleanValue()); } } public void stop() { if (rawStoreDaemon != null) rawStoreDaemon.stop(); } /* ** Methods of TransactionFactory */ /** Get the LockFactory to use with this store. */ public LockFactory getLockFactory() { return lockFactory; } /** Database creation finished @exception StandardException standard cloudscape error policy */ public void createFinished() throws StandardException { if (!inCreateNoLog) { throw StandardException.newException(SQLState.XACT_CREATE_NO_LOG); } // make sure there is no active update transaction if (ttab.hasActiveUpdateTransaction()) { throw StandardException.newException(SQLState.XACT_CREATE_NO_LOG); } inCreateNoLog = false; } /** * Common work done to create local or global transactions. * * @param rsf the raw store factory creating this xact. * @param cm the current context manager to associate the xact with. * @param compatibilitySpace * if null, use the transaction being created, else if * non-null use this compatibilitySpace. * * @exception StandardException Standard exception policy. **/ private RawTransaction startCommonTransaction( RawStoreFactory rsf, ContextManager cm, boolean readOnly, Object compatibilitySpace, String xact_context_id, String transName, boolean excludeMe) throws StandardException { if (SanityManager.DEBUG) { if (rawStoreFactory != null) SanityManager.ASSERT( rawStoreFactory == rsf, "raw store factory different"); SanityManager.ASSERT( cm == contextFactory.getCurrentContextManager()); } Xact xact = new Xact(this, logFactory, dataFactory, readOnly, compatibilitySpace); xact.setTransName(transName); pushTransactionContext(cm, xact_context_id, xact, false /* abortAll */, rsf, excludeMe /* excludeMe during quiesce state */); return xact; } public RawTransaction startTransaction( RawStoreFactory rsf, ContextManager cm, String transName) throws StandardException { return(startCommonTransaction( rsf, cm, false, null, USER_CONTEXT_ID, transName, true)); } public RawTransaction startNestedReadOnlyUserTransaction( RawStoreFactory rsf, Object compatibilitySpace, ContextManager cm, String transName) throws StandardException { return(startCommonTransaction( rsf, cm, true, compatibilitySpace, NESTED_READONLY_USER_CONTEXT_ID, transName, false)); } public RawTransaction startNestedUpdateUserTransaction( RawStoreFactory rsf, ContextManager cm, String transName) throws StandardException { return(startCommonTransaction( rsf, cm, false, null, NESTED_UPDATE_USER_CONTEXT_ID, transName, true)); } public RawTransaction startGlobalTransaction( RawStoreFactory rsf, ContextManager cm, int format_id, byte[] global_id, byte[] branch_id) throws StandardException { GlobalXactId gid = new GlobalXactId(format_id, global_id, branch_id); if (ttab.findTransactionContextByGlobalId(gid) != null) { throw StandardException.newException(SQLState.STORE_XA_XAER_DUPID); } RawTransaction xact = startCommonTransaction( rsf, cm, false, null, USER_CONTEXT_ID, AccessFactoryGlobals.USER_TRANS_NAME, true); xact.setTransactionId(gid, xact.getId()); return(xact); } public RawTransaction findUserTransaction( RawStoreFactory rsf, ContextManager contextMgr, String transName) throws StandardException { if (SanityManager.DEBUG) { SanityManager.ASSERT( contextMgr == contextFactory.getCurrentContextManager(), "passed in context mgr not the same as current context mgr"); if (rawStoreFactory != null) SanityManager.ASSERT( rawStoreFactory == rsf, "raw store factory different"); } XactContext xc = (XactContext)contextMgr.getContext(USER_CONTEXT_ID); if (xc == null) return startTransaction(rsf, contextMgr, transName); else return xc.getTransaction(); } public RawTransaction startNestedTopTransaction(RawStoreFactory rsf, ContextManager cm) throws StandardException { if (SanityManager.DEBUG) { if (rawStoreFactory != null) SanityManager.ASSERT( rawStoreFactory == rsf, "raw store factory different"); } Xact xact = new Xact(this, logFactory, dataFactory, false, null); // hold latches etc. past commit in NTT xact.setPostComplete(); pushTransactionContext(cm, NTT_CONTEXT_ID, xact, true /* abortAll */, rsf, true /* excludeMe during quiesce state*/); return xact; } public RawTransaction startInternalTransaction(RawStoreFactory rsf, ContextManager cm) throws StandardException { if (SanityManager.DEBUG) { if (rawStoreFactory != null) SanityManager.ASSERT( rawStoreFactory == rsf, "raw store factory different"); } Xact xact = new InternalXact(this, logFactory, dataFactory); pushTransactionContext(cm, INTERNAL_CONTEXT_ID, xact, true /* abortAll*/, rsf, true /* excludeMe during quiesce state */); return xact; } /* * the following TransactionFactory methods are to support recovery and * should only be used by recovery! */ /** Find the TransactionTableEntry with the given ID and make the passed in transaction assume the identity and properties of that TransactionTableEntry. Used in recovery only. */ public boolean findTransaction(TransactionId id, RawTransaction tran) { return ttab.findAndAssumeTransaction(id, tran); } /** Rollback all active transactions that has updated the raw store. Use the recovery Transaction that is passed in to do all the work. Used in recovery only. <P> Transactions are rolled back in the following order: <OL> <LI>internal transactions in reversed beginXact chronological order, <LI>all other transactions in reversed beginXact chronological order, </NL> @param recoveryTransaction use this transaction to do all the user transaction work @exception StandardException any exception thrown during rollback */ public void rollbackAllTransactions( RawTransaction recoveryTransaction, RawStoreFactory rsf) throws StandardException { if (SanityManager.DEBUG) { if (rawStoreFactory != null) SanityManager.ASSERT( rawStoreFactory == rsf, "raw store factory different"); SanityManager.ASSERT( recoveryTransaction != null, "recovery transaction null"); } int irbcount = 0; // First undo internal transactions if there is any if (ttab.hasRollbackFirstTransaction()) { RawTransaction internalTransaction = startInternalTransaction(rsf, recoveryTransaction.getContextManager()); // make this transaction be aware that it is being used by recovery internalTransaction.recoveryTransaction(); if (SanityManager.DEBUG) SanityManager.ASSERT( internalTransaction.handlesPostTerminationWork() == false, "internal recovery xact handles post termination work"); while(ttab.getMostRecentRollbackFirstTransaction( internalTransaction)) { irbcount++; internalTransaction.abort(); } internalTransaction.close(); } if (SanityManager.DEBUG) { SanityManager.ASSERT( ttab.hasRollbackFirstTransaction() == false, "cant rollback user xacts with existing active internal xacts"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -