/// <summary> /// Find the working order than contains this credit card. /// </summary> /// <param name="transaction">The transaction object.</param> /// <param name="creditCardId">The credit card id.</param> /// <returns>The working order that contains this credit card.</returns> private WorkingOrderRow FindWorkingOrder(DataModelTransaction transaction, Guid creditCardId) { CreditCardRow creditCardRow = DataModel.CreditCard.CreditCardKey.Find(creditCardId); creditCardRow.AcquireReaderLock(transaction); ConsumerRow consumerRow = creditCardRow.ConsumerRow; creditCardRow.ReleaseLock(transaction.TransactionId); consumerRow.AcquireReaderLock(transaction); ConsumerDebtRow[] consumerDebtRows = consumerRow.GetConsumerDebtRows(); ConsumerTrustRow[] consumerTrustRows = consumerRow.GetConsumerTrustRows(); consumerRow.ReleaseLock(transaction.TransactionId); // There really should only be one ConsumerDebtRow (if there is one at all). foreach (ConsumerDebtRow consumerDebtRow in consumerDebtRows) { consumerDebtRow.AcquireReaderLock(transaction); SecurityRow securityRow = consumerDebtRow.SecurityRow; consumerDebtRow.ReleaseLock(transaction.TransactionId); securityRow.AcquireReaderLock(transaction); WorkingOrderRow[] workingOrderRows = securityRow.GetWorkingOrderRowsByFK_Security_WorkingOrder_SecurityId(); securityRow.ReleaseLock(transaction.TransactionId); // There really should only be one WorkingOrderRow, so return the first one we find. foreach (WorkingOrderRow workingOrderRow in workingOrderRows) { return(workingOrderRow); } } // There really should only be one ConsumerTrustRow (if there is one at all). foreach (ConsumerTrustRow consumerTrustRow in consumerTrustRows) { consumerTrustRow.AcquireReaderLock(transaction); SecurityRow securityRow = consumerTrustRow.SecurityRow; consumerTrustRow.ReleaseLock(transaction.TransactionId); securityRow.AcquireReaderLock(transaction); WorkingOrderRow[] workingOrderRows = securityRow.GetWorkingOrderRowsByFK_Security_WorkingOrder_SecurityId(); securityRow.ReleaseLock(transaction.TransactionId); // There really should only be one WorkingOrderRow, so return the first one we find. foreach (WorkingOrderRow workingOrderRow in workingOrderRows) { return(workingOrderRow); } } return(null); }
/// <summary> /// Get the securityId of the security this consumer is a part of. /// </summary> /// <param name="transaction">The current transaction.</param> /// <param name="consumerId">The consumerId.</param> /// <returns>The securityId of the security.</returns> public static Guid GetBlotterForConsumer(DataModelTransaction transaction, Guid consumerId) { Guid blotterId = Guid.Empty; ConsumerRow consumerRow = DataModel.Consumer.ConsumerKey.Find(consumerId); ConsumerDebtRow[] consumerDebtRows; ConsumerTrustRow[] consumerTrustRows; SecurityRow securityRow; WorkingOrderRow[] workingOrderRows; if (consumerRow == null) { throw new FaultException <RecordNotFoundFault>( new RecordNotFoundFault("Consumer", new object[] { consumerId }), "The consumer has been deleted."); } consumerRow.AcquireReaderLock(transaction); consumerDebtRows = consumerRow.GetConsumerDebtRows(); consumerTrustRows = consumerRow.GetConsumerTrustRows(); consumerRow.ReleaseLock(transaction.TransactionId); if (consumerDebtRows.Length > 0) { consumerDebtRows[0].AcquireReaderLock(transaction); securityRow = consumerDebtRows[0].SecurityRow; consumerDebtRows[0].ReleaseLock(transaction.TransactionId); } else if (consumerTrustRows.Length > 0) { consumerTrustRows[0].AcquireReaderLock(transaction); securityRow = consumerTrustRows[0].SecurityRow; consumerTrustRows[0].ReleaseLock(transaction.TransactionId); } else { throw new FaultException <RecordNotFoundFault>( new RecordNotFoundFault("Consumer", new object[] { consumerId }), "This consumer record is an orphan - it is not related to any security."); } securityRow.AcquireReaderLock(transaction); workingOrderRows = securityRow.GetWorkingOrderRowsByFK_Security_WorkingOrder_SecurityId(); securityRow.ReleaseLock(transaction.TransactionId); if (workingOrderRows.Length > 0) { workingOrderRows[0].AcquireReaderLock(transaction); blotterId = workingOrderRows[0].BlotterId; workingOrderRows[0].ReleaseLock(transaction.TransactionId); } else { throw new FaultException <RecordNotFoundFault>( new RecordNotFoundFault("Consumer", new object[] { consumerId }), "This consumer record is an orphan - it is not related to any working order."); } return(blotterId); }
/// <summary> /// Delete a WorkingOrderRow. /// </summary> /// <param name="dataModel">The data model.</param> /// <param name="transaction">The current transaction.</param> /// <param name="workingOrderRow">The working order row to delete.</param> /// <returns>Error code of any failure, or Success.</returns> public ErrorCode DeleteRow(DataModel dataModel, DataModelTransaction transaction, WorkingOrderRow workingOrderRow) { SecurityRow securityRow = null; EntityRow securityEntityRow = null; MatchRow[] matchRows; ConsumerDebtRow[] consumerDebtRows; ConsumerTrustRow[] consumerTrustRows; CreditCardRow creditCardRow = null; ConsumerRow consumerRow = null; Guid blotterId; Guid securityEntityId = Guid.Empty; Int64 securityEntityRowVersion = 0; Guid consumerId = Guid.Empty; Int64 consumerRowVersion = 0; Guid creditCardId = Guid.Empty; Int64 creditCardRowVersion = 0; Boolean consumerStillInUse = false; workingOrderRow.AcquireWriterLock(transaction.TransactionId, DataModel.LockTimeout); if (workingOrderRow.RowState == DataRowState.Deleted || workingOrderRow.RowState == DataRowState.Detached) { workingOrderRow.ReleaseLock(transaction.TransactionId); return(ErrorCode.RecordNotFound); } else { transaction.AddLock(workingOrderRow); } blotterId = workingOrderRow.BlotterId; securityRow = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId; matchRows = workingOrderRow.GetMatchRows(); if (matchRows != null) { foreach (MatchRow matchRow in matchRows) { if (IsSettled(transaction, matchRow)) { return(ErrorCode.RecordExists); } } } if (!DataModelFilters.HasAccess(transaction, TradingSupport.UserId, blotterId, AccessRight.Write)) { workingOrderRow.ReleaseLock(transaction.TransactionId); return(ErrorCode.AccessDenied); } securityRow.AcquireWriterLock(transaction.TransactionId, DataModel.LockTimeout); if (securityRow.RowState == DataRowState.Deleted || securityRow.RowState == DataRowState.Detached) { workingOrderRow.ReleaseLock(transaction.TransactionId); securityRow.ReleaseWriterLock(transaction.TransactionId); return(ErrorCode.RecordNotFound); } securityEntityRow = securityRow.EntityRow; consumerDebtRows = securityRow.GetConsumerDebtRows(); consumerTrustRows = securityRow.GetConsumerTrustRows(); securityRow.ReleaseWriterLock(transaction.TransactionId); securityEntityRow.AcquireWriterLock(transaction); if (securityEntityRow.RowState == DataRowState.Deleted || securityEntityRow.RowState == DataRowState.Detached) { workingOrderRow.ReleaseLock(transaction.TransactionId); securityEntityRow.ReleaseLock(transaction.TransactionId); return(ErrorCode.RecordNotFound); } securityEntityId = securityEntityRow.EntityId; securityEntityRowVersion = securityEntityRow.RowVersion; securityEntityRow.ReleaseLock(transaction.TransactionId); if (consumerTrustRows.Length > 0 && consumerDebtRows.Length > 0) { EventLog.Warning("Deleting a working order associated with both ConsumerDebt and ConsumerTrust rows"); } else if (consumerDebtRows.Length > 1) { EventLog.Warning("Deleting a working order associated with more than one ConsumerDebt row"); } else if (consumerTrustRows.Length > 1) { EventLog.Warning("Deleting a working order associated with more than one ConsumerTrust row"); } if (consumerDebtRows.Length == 1) { ConsumerDebtRow consumerDebtRow = consumerDebtRows[0]; consumerDebtRow.AcquireWriterLock(transaction); if (consumerDebtRow.RowState == DataRowState.Deleted || consumerDebtRow.RowState == DataRowState.Detached) { } else { creditCardRow = consumerDebtRow.CreditCardRow; consumerRow = consumerDebtRow.ConsumerRow; } consumerDebtRow.ReleaseLock(transaction.TransactionId); } else if (consumerTrustRows.Length == 1) { ConsumerTrustRow consumerTrustRow = consumerTrustRows[0]; consumerTrustRow.AcquireWriterLock(transaction); if (consumerTrustRow.RowState == DataRowState.Deleted || consumerTrustRow.RowState == DataRowState.Detached) { } else { consumerRow = consumerTrustRow.ConsumerRow; } consumerTrustRow.ReleaseLock(transaction.TransactionId); } if (consumerRow != null) { consumerRow.AcquireWriterLock(transaction); if (consumerRow.RowState == DataRowState.Deleted || consumerRow.RowState == DataRowState.Detached) { consumerRow = null; } else { consumerStillInUse = consumerRow.GetConsumerDebtRows().Length > 1; consumerId = consumerRow.ConsumerId; consumerRowVersion = consumerRow.RowVersion; } consumerRow.ReleaseLock(transaction.TransactionId); } if (creditCardRow != null) { creditCardRow.AcquireWriterLock(transaction); if (creditCardRow.RowState == DataRowState.Deleted || creditCardRow.RowState == DataRowState.Detached) { creditCardRow = null; } else { creditCardId = creditCardRow.ConsumerId; creditCardRowVersion = creditCardRow.RowVersion; } creditCardRow.ReleaseLock(transaction.TransactionId); } //gonna get the lock on the workingOrder and let the txn commit/rollback get rid of it //this will basically wrap the delete row //action in a critical section because the first //reader lock in the method is on the workingOrder row //workingOrderRow.AcquireWriterLock(transaction.TransactionId, DataModel.LockTimeout); if (workingOrderRow.RowState == DataRowState.Deleted || workingOrderRow.RowState == DataRowState.Detached) { workingOrderRow.ReleaseLock(transaction.TransactionId); return(ErrorCode.RecordNotFound); } //securityRow.AcquireWriterLock(transaction.TransactionId, DataModel.LockTimeout); //if(securityRow.RowState == DataRowState.Deleted || // securityRow.RowState == DataRowState.Detached) //{ // workingOrderRow.ReleaseLock(transaction.TransactionId); // return ErrorCode.RecordNotFound; //} if (creditCardRow != null && consumerStillInUse) { dataModel.DestroyCreditCard(new object[] { creditCardId }, creditCardRowVersion); } if (consumerRow != null && !consumerStillInUse) { dataModel.DestroyConsumer(new object[] { consumerId }, consumerRowVersion); } dataModel.DestroyEntity(new object[] { securityEntityId }, securityEntityRowVersion); return(ErrorCode.Success); }