public override void doWork(Locks_Client client) { client.ReleaseExclusive(_resourceType, _key); }
/// <summary> /// You MUST hold a label write lock before you call this method. /// However the label write lock is temporarily released while populating the index backing the constraint. /// It goes a little like this: /// <ol> /// <li>Prerequisite: Getting here means that there's an open schema transaction which has acquired the /// LABEL WRITE lock.</li> /// <li>Index schema rule which is backing the constraint is created in a nested mini-transaction /// which doesn't acquire any locking, merely adds tx state and commits so that the index rule is applied /// to the store, which triggers the index population</li> /// <li>Release the LABEL WRITE lock</li> /// <li>Await index population to complete</li> /// <li>Acquire the LABEL WRITE lock (effectively blocking concurrent transactions changing /// data related to this constraint, and it so happens, most other transactions as well) and verify /// the uniqueness of the built index</li> /// <li>Leave this method, knowing that the uniqueness constraint rule will be added to tx state /// and this tx committed, which will create the uniqueness constraint</li> /// </ol> /// </summary> //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: public long createUniquenessConstraintIndex(org.neo4j.kernel.impl.api.KernelTransactionImplementation transaction, org.neo4j.internal.kernel.api.schema.SchemaDescriptor descriptor, String provider) throws org.neo4j.internal.kernel.api.exceptions.TransactionFailureException, org.neo4j.internal.kernel.api.exceptions.schema.CreateConstraintFailureException, org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException, org.neo4j.kernel.api.exceptions.schema.AlreadyConstrainedException public virtual long CreateUniquenessConstraintIndex(KernelTransactionImplementation transaction, SchemaDescriptor descriptor, string provider) { UniquenessConstraintDescriptor constraint = ConstraintDescriptorFactory.uniqueForSchema(descriptor); _log.info("Starting constraint creation: %s.", constraint.OwnedIndexDescriptor()); IndexReference index; SchemaRead schemaRead = transaction.SchemaRead(); try { index = GetOrCreateUniquenessConstraintIndex(schemaRead, transaction.TokenRead(), descriptor, provider); } catch (AlreadyConstrainedException e) { throw e; } catch (Exception e) when(e is SchemaKernelException || e is IndexNotFoundKernelException) { throw new CreateConstraintFailureException(constraint, e); } bool success = false; bool reacquiredLabelLock = false; Locks_Client locks = transaction.StatementLocks().pessimistic(); try { long indexId = schemaRead.IndexGetCommittedId(index); IndexProxy proxy = _indexingService.getIndexProxy(indexId); // Release the LABEL WRITE lock during index population. // At this point the integrity of the constraint to be created was checked // while holding the lock and the index rule backing the soon-to-be-created constraint // has been created. Now it's just the population left, which can take a long time locks.ReleaseExclusive(descriptor.KeyType(), descriptor.KeyId()); AwaitConstraintIndexPopulation(constraint, proxy, transaction); _log.info("Constraint %s populated, starting verification.", constraint.OwnedIndexDescriptor()); // Index population was successful, but at this point we don't know if the uniqueness constraint holds. // Acquire LABEL WRITE lock and verify the constraints here in this user transaction // and if everything checks out then it will be held until after the constraint has been // created and activated. locks.AcquireExclusive(transaction.LockTracer(), descriptor.KeyType(), descriptor.KeyId()); reacquiredLabelLock = true; _indexingService.getIndexProxy(indexId).verifyDeferredConstraints(_nodePropertyAccessor); _log.info("Constraint %s verified.", constraint.OwnedIndexDescriptor()); success = true; return(indexId); } catch (SchemaKernelException e) { throw new System.InvalidOperationException(string.Format("Index ({0}) that we just created does not exist.", descriptor), e); } catch (IndexNotFoundKernelException e) { throw new TransactionFailureException(string.Format("Index ({0}) that we just created does not exist.", descriptor), e); } catch (IndexEntryConflictException e) { throw new UniquePropertyValueValidationException(constraint, VERIFICATION, e); } catch (Exception e) when(e is InterruptedException || e is IOException) { throw new CreateConstraintFailureException(constraint, e); } finally { if (!success) { if (!reacquiredLabelLock) { locks.AcquireExclusive(transaction.LockTracer(), descriptor.KeyType(), descriptor.KeyId()); } if (IndexStillExists(schemaRead, descriptor, index)) { DropUniquenessConstraintIndex(( IndexDescriptor )index); } } } }