/// <summary> /// update the order modify time, but dont save it. this will be used as a message to /// re-process the order /// </summary> /// <param name="utcModTime"></param> /// <param name="workingOrderId"></param> private static void UpdateOrderModifyTime(DateTime utcModTime, Guid workingOrderId) { using (TransactionScope transactionScope = new TransactionScope()) { // This provides a context for any transactions. DataModelTransaction dataModelTransaction = DataModelTransaction.Current; WorkingOrderRow workingOrderRow = DataModel.WorkingOrder.WorkingOrderKey.Find(workingOrderId); if (workingOrderRow == null) { return; } DataModel dataModel = new DataModel(); workingOrderRow.AcquireWriterLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); try { if (workingOrderRow.RowState == System.Data.DataRowState.Deleted || workingOrderRow.RowState == System.Data.DataRowState.Detached) { return; } DataModel.DataLock.EnterWriteLock(); try { workingOrderRow.BeginEdit(); workingOrderRow[DataModel.WorkingOrder.ModifiedTimeColumn] = utcModTime; } finally { workingOrderRow.EndEdit(); workingOrderRow.RejectChanges(); DataModel.DataLock.ExitWriteLock(); } } finally { workingOrderRow.ReleaseWriterLock(dataModelTransaction.TransactionId); } } }
/// <summary> /// Update a consumer. /// </summary> /// <param name="entity">The ConsumerTrust's Entity row.</param> /// <returns>The ConsumerId of the Consumer row.</returns> private Guid UpdateConsumer(EntityRow entity) { DataModel dataModel = new DataModel(); DataModelTransaction dataModelTransaction = DataModelTransaction.Current; DateTime modified = DateTime.UtcNow; CountryRow country; Guid countryId; Guid? provinceId = null; EntityRow dollars; Guid dollarsId; ConsumerRow consumer = null; ConsumerTrustRow consumerTrust = null; SecurityRow security = null; WorkingOrderRow workingOrder = null; MatchRow[] matches; Guid consumerId; Guid consumerTrustId; Guid entityId; Guid securityId; Guid workingOrderId; Int64 consumerVersion; Int64 consumerTrustVersion; Int64 entityVersion; Int64 securityVersion; Int64 workingOrderVersion; Boolean updateConsumer = false; Boolean updateConsumerTrust = false; Boolean updateEntity = false; Boolean updateSecurity = false; country = TradingSupport.FindCountryByKey( this.Record.ConfigurationId, "FK_Country_Security", new object[] { this.Record.CountryCode }); countryId = country.CountryId; country.ReleaseReaderLock(dataModelTransaction.TransactionId); if (this.Record.ProvinceCode != null) { ProvinceRow province = TradingSupport.FindProvinceByKey( this.Record.ConfigurationId, "FK_Province_Consumer", new object[] { this.Record.ProvinceCode }); provinceId = province.ProvinceId; province.ReleaseReaderLock(dataModelTransaction.TransactionId); } dollars = TradingSupport.FindEntityByKey( this.Record.ConfigurationId, "FK_Security_WorkingOrder_SettlementId", new object[] { this.Record.Currency }); dollarsId = dollars.EntityId; dollars.ReleaseReaderLock(dataModelTransaction.TransactionId); try { entity.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); entityId = entity.EntityId; entityVersion = entity.RowVersion; if (TradingSupport.IsColumnOld(entity, "Name", this.Record.OriginalAccountNumber)) { updateEntity = true; } } finally { entity.ReleaseLock(dataModelTransaction.TransactionId); } try { security = DataModel.Security.SecurityKey.Find(entityId); security.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); securityId = entityId; securityVersion = security.RowVersion; workingOrder = security.GetWorkingOrderRowsByFK_Security_WorkingOrder_SecurityId()[0]; if (TradingSupport.IsColumnOld(security, "CountryId", countryId)) { updateSecurity = true; } } finally { security.ReleaseLock(dataModelTransaction.TransactionId); } // Control the working order: workingOrder.AcquireWriterLock(dataModelTransaction); try { consumerTrust = DataModel.ConsumerTrust.ConsumerTrustKey.Find(entityId); consumerTrust.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); consumerTrustId = consumerTrust.ConsumerTrustId; consumerTrustVersion = consumerTrust.RowVersion; consumer = DataModel.Consumer.ConsumerKey.Find(consumerTrust.ConsumerId); if (TradingSupport.IsColumnOld(consumerTrust, "SavingsAccount", this.Record.SavingsAccount) || TradingSupport.IsColumnOld(consumerTrust, "SavingsBalance", this.Record.SavingsBalance) || TradingSupport.IsColumnOld(consumerTrust, "Tag", this.Record.Tag)) { updateConsumerTrust = true; } } finally { consumerTrust.ReleaseLock(dataModelTransaction.TransactionId); } try { consumer.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); consumerId = consumer.ConsumerId; consumerVersion = consumer.RowVersion; if (TradingSupport.IsColumnOld(consumer, "Address1", this.Record.Address1) || TradingSupport.IsColumnOld(consumer, "Address2", this.Record.Address2) || TradingSupport.IsColumnOld(consumer, "BankAccountNumber", this.Record.BankAccountNumber) || TradingSupport.IsColumnOld(consumer, "BankRoutingNumber", this.Record.BankRoutingNumber) || TradingSupport.IsColumnOld(consumer, "City", this.Record.City) || TradingSupport.IsColumnOld(consumer, "DateOfBirth", this.Record.DateOfBirth) || TradingSupport.IsColumnOld(consumer, "FirstName", this.Record.FirstName) || TradingSupport.IsColumnOld(consumer, "IsEmployed", this.Record.IsEmployed) || TradingSupport.IsColumnOld(consumer, "LastName", this.Record.LastName) || TradingSupport.IsColumnOld(consumer, "PostalCode", this.Record.PostalCode) || TradingSupport.IsColumnOld(consumer, "MiddleName", this.Record.MiddleName) || TradingSupport.IsColumnOld(consumer, "PhoneNumber", this.Record.PhoneNumber) || TradingSupport.IsColumnOld(consumer, "ProvinceId", provinceId) || TradingSupport.IsColumnOld(consumer, "SocialSecurityNumber", this.Record.SocialSecurityNumber) || TradingSupport.IsColumnOld(consumer, "Suffix", this.Record.Suffix)) { updateConsumer = true; } } finally { consumer.ReleaseLock(dataModelTransaction.TransactionId); } try { //workingOrder.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); workingOrderId = workingOrder.WorkingOrderId; workingOrderVersion = workingOrder.RowVersion; matches = workingOrder.GetMatchRows(); } finally { //workingOrder.ReleaseLock(dataModelTransaction.TransactionId); } foreach (MatchRow match in matches) { if (WorkingOrderPersistence.IsSettled(dataModelTransaction, match)) { throw new FaultException <SecurityFault>( new SecurityFault("Cannot update account that is settled") { FaultCode = ErrorCode.RecordExists }, "Cannot update account that is settled"); } } // We need write access to the containing blotter in order to add a record to it. if (!TradingSupport.HasAccess(dataModelTransaction, PersistenceHelper.GetBlotterForConsumer(dataModelTransaction, consumerId), AccessRight.Write)) { throw new SecurityException("Current user does not have write access to the original blotter"); } if (updateConsumer) { dataModel.UpdateConsumer( this.Record.Address1 != null ? (object)this.Record.Address1 : DBNull.Value, this.Record.Address2 != null ? (object)this.Record.Address2 : DBNull.Value, this.Record.BankAccountNumber != null ? (object)this.Record.BankAccountNumber : DBNull.Value, this.Record.BankRoutingNumber != null ? (object)this.Record.BankRoutingNumber : DBNull.Value, this.Record.City != null ? (object)this.Record.City : DBNull.Value, consumerId, new object[] { consumerId }, this.Record.DateOfBirth != null ? (object)this.Record.DateOfBirth.Value : DBNull.Value, null, null, this.Record.FirstName != null ? (object)this.Record.FirstName : DBNull.Value, this.Record.IsEmployed != null ? (object)this.Record.IsEmployed.Value : DBNull.Value, this.Record.LastName != null ? (object)this.Record.LastName : DBNull.Value, this.Record.MiddleName != null ? (object)this.Record.MiddleName : DBNull.Value, this.Record.PhoneNumber != null ? (object)StringUtilities.CleanUpAlphaNumericString(this.Record.PhoneNumber) : DBNull.Value, this.Record.PostalCode != null ? (object)this.Record.PostalCode : DBNull.Value, provinceId, consumerVersion, this.Record.Salutation, StringUtilities.CleanUpAlphaNumericString(this.Record.SocialSecurityNumber), this.Record.Suffix != null ? (object)this.Record.Suffix : DBNull.Value); } if (updateConsumerTrust) { dataModel.UpdateConsumerTrust( null, consumerTrustId, new object[] { consumerTrustId }, null, null, consumerTrustVersion, this.Record.SavingsAccount, this.Record.SavingsBalance, this.Record.Tag != null ? (object)this.Record.Tag : DBNull.Value, null, null); } if (updateEntity) { dataModel.UpdateEntity( null, null, entityId, new object[] { entityId }, null, null, null, null, null, null, null, null, null, null, null, modified, this.Record.SavingsEntityCode, entityVersion, null, null); } if (updateSecurity) { dataModel.UpdateSecurity( null, countryId, null, null, null, 1, 1, securityVersion, securityId, new object[] { securityId }, null, null, null); } dataModel.UpdateWorkingOrder( null, this.Record.Blotter, null, null, null, null, null, null, null, null, null, null, null, modified, TradingSupport.UserId, null, workingOrderVersion, null, null, dollarsId, null, null, StatusMap.FromCode(Status.New), null, null, null, null, null, null, modified, workingOrderId, new object[] { workingOrderId }); return(consumerId); }
/// <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); }