public void Rollback(string savePoint) { if (!String.IsNullOrEmpty(savePoint)) { throw new NotSupportedException(); } if (IsClosed) { return; } try { Status = TransactionStatus.Rollback; TableSystem.Rollback(this); // TODO: fire an event } catch (TransactionException) { throw; } catch (Exception ex) { throw new TransactionException("An error occurred while rolling back the transaction", ex); } finally { Finish(); } }
public async Task <IActionResult> Edit(int id, [Bind("Id,TableSystemName")] TableSystem tableSystem) { if (id != tableSystem.Id) { return(NotFound()); } if (ModelState.IsValid) { try { _context.Update(tableSystem); await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!TableSystemExists(tableSystem.Id)) { return(NotFound()); } else { throw; } } return(RedirectToAction(nameof(Index))); } return(View(tableSystem)); }
public async Task <IActionResult> Create([Bind("Id,TableSystemName")] TableSystem tableSystem) { if (ModelState.IsValid) { _context.Add(tableSystem); await _context.SaveChangesAsync(); return(RedirectToAction(nameof(Index))); } return(View(tableSystem)); }
private CommitTableInfo[] GetNormalizedChangedTables() { // Create a normalized list of TableSource of all tables that // were either changed (and not dropped), and created (and not dropped). // This list represents all tables that are either new or changed in // this transaction. var normalizedChangedTables = new List <CommitTableInfo>(8); // Add all tables that were changed and not dropped in this transaction. normalizedChangedTables.AddRange( ChangedTables.Select(tableJournal => new { tableJournal, tableId = tableJournal.TableId }) .Where(t => !DroppedTables.Contains(t.tableId)) .Select(t => new { t, source = TableSystem.GetTableSource(t.tableId) }) .Select(t => new CommitTableInfo { Master = t.source, Journal = t.t.tableJournal, ChangesSinceCommit = t.source.FindChangesSinceCommit(Id).ToArray() })); // Add all tables that were created and not dropped in this transaction. foreach (var tableId in CreatedTables) { // If this table is not dropped in this transaction then this is a // new table in this transaction. if (!DroppedTables.Contains(tableId)) { TableSource masterTable = TableSystem.GetTableSource(tableId); if (!CommitTableListContains(normalizedChangedTables, masterTable)) { // This is for entries that are created but modified (no journal). var tableInfo = new CommitTableInfo { Master = masterTable }; normalizedChangedTables.Add(tableInfo); } } } return(normalizedChangedTables.ToArray()); }
private TableSource[] GetNormalizedDroppedTables() { // Create a normalized list of TableSource of all tables that // were dropped (and not created) in this transaction. This list // represents tables that will be dropped if the transaction // successfully commits. var normalizedDroppedTables = new List <TableSource>(8); foreach (var tableId in DroppedTables) { // Was this dropped table also created? If it was created in this // transaction then we don't care about it. if (!CreatedTables.Contains(tableId)) { TableSource masterTable = TableSystem.GetTableSource(tableId); normalizedDroppedTables.Add(masterTable); } } return(normalizedDroppedTables.ToArray()); }
/* @brief:系统启动注册事件 * @return void */ public static void RegistCallback(bool bClear = true) { IGameReceiver iGameRecv = Game.Instance.mGameRecv; if (iGameRecv == null) { LogSystem.Log("Error!! WorldStage::RegistCallback iGameRecv is null"); return; } GameSceneManager.RegistCallback(iGameRecv, bClear); ObjectManager.RegistCallback(iGameRecv, bClear); RecordSystem.RegistCallback(iGameRecv, bClear); CustomSystem.RegistCallback(iGameRecv, bClear); ViewSystem.RegistCallback(iGameRecv, bClear); TableSystem.RegistCallback(); ServerCustom.RegistCallBack(); iGameRecv.RegistCallBack("on_msg_tracert", on_msg_tracert); iGameRecv.RegistCallBack("on_terminate", on_terminate); }
public IEnumerable <TableSource> Execute(IList <ObjectCommitState> objectStates) { var changedTablesList = new List <TableSource>(); // This is a transaction that will represent the view of the database // at the end of the commit ITransaction checkTransaction = null; bool entriesCommitted = false; try { // ---- Commit check stage ---- CheckConflicts(objectStates); // Tests passed so go on to commit, // ---- Commit stage ---- var normalizedChangedTables = GetNormalizedChangedTables(); var normalizedDroppedTables = GetNormalizedDroppedTables(); // We now need to create a ITransaction object that we // use to send to the triggering mechanism. This // object represents a very specific view of the // transaction. This view contains the latest version of changed // tables in this transaction. It also contains any tables that have // been created by this transaction and does not contain any tables // that have been dropped. Any tables that have not been touched by // this transaction are shown in their current committed state. // To summarize - this view is the current view of the database plus // any modifications made by the transaction that is being committed. // How this works - All changed tables are merged with the current // committed table. All created tables are added into check_transaction // and all dropped tables are removed from check_transaction. If // there were no other changes to a table between the time the // transaction was created and now, the view of the table in the // transaction is used, otherwise the latest changes are merged. // Note that this view will be the view that the database will // ultimately become if this transaction successfully commits. Also, // you should appreciate that this view is NOT exactly the same as // the current trasaction view because any changes that have been // committed by concurrent transactions will be reflected in this view. // Create a new transaction of the database which will represent the // committed view if this commit is successful. checkTransaction = TableSystem.Database.CreateTransaction(IsolationLevel.Serializable); // Overwrite this view with tables from this transaction that have // changed or have been added or dropped. // (Note that order here is important). First drop any tables from // this view. foreach (TableSource masterTable in normalizedDroppedTables) { // Drop this table in the current view checkTransaction.State.RemoveVisibleTable(masterTable); } // Now add any changed tables to the view. // Represents view of the changed tables var changedTableSource = FindChangedTables(checkTransaction, normalizedChangedTables); // The 'checkTransaction' now represents the view the database will be // if the commit succeeds. We Lock 'checkTransaction' so it is // Read-only (the view is immutable). checkTransaction.ReadOnly(true); CheckConstraintViolations(checkTransaction, normalizedChangedTables, changedTableSource); // Deferred trigger events. FireChangeEvents(normalizedChangedTables); // NOTE: This isn't as fail safe as it could be. We really need to // do the commit in two phases. The first writes updated indices to // the index files. The second updates the header pointer for the // respective table. Perhaps we can make the header update // procedure just one file Write. // Finally, at this point all constraint checks have passed and the // changes are ready to finally be committed as permanent changes // to the Composite. All that needs to be done is to commit our // IIndexSet indices for each changed table as final. // ISSUE: Should we separate the 'committing of indexes' changes and // 'committing of delete/add flags' to make the FS more robust? // It would be more robust if all indexes are committed in one go, // then all table flag data. // Set flag to indicate we have committed entries. entriesCommitted = true; // For each change to each table, foreach (CommitTableInfo tableInfo in normalizedChangedTables) { // Get the journal that details the change to the table. var changeJournal = tableInfo.Journal; if (changeJournal != null) { // Get the master table with this table id. TableSource master = tableInfo.Master; // Commit the changes to the table. // We use 'this.commit_id' which is the current commit level we are // at. master.CommitTransactionChange(TableSystem.Database.OpenTransactions.CurrentCommitId, changeJournal, tableInfo.IndexSet); // Add to 'changed_tables_list' changedTablesList.Add(master); } } // Only do this if we've created or dropped tables. if (CreatedTables.Any() || DroppedTables.Any()) { // Update the committed tables in the Composite state. // This will update and synchronize the headers in this Composite. TableSystem.CommitToTables(CreatedTables, DroppedTables); } // Update the namespace clash list if (ObjectsCreated.Any() || ObjectsDropped.Any()) { objectStates.Add(new ObjectCommitState(Id, ObjectsCreated, ObjectsDropped)); } } finally { try { // If entries_committed == false it means we didn't get to a point // where any changed tables were committed. Attempt to rollback the // changes in this transaction if they haven't been committed yet. if (entriesCommitted == false) { // For each change to each table, foreach (ITableEventRegistry changeJournal in ChangedTables) { // The table the changes were made to. int tableId = changeJournal.TableId; // Get the master table with this table id. TableSource master = TableSystem.GetTableSource(tableId); // Commit the rollback on the table. master.RollbackTransactionChange(changeJournal); } // TODO: Notify the system we're rolling back } } finally { try { // Dispose the 'checkTransaction' if (checkTransaction != null) { checkTransaction.Dispose(); TableSystem.CloseTransaction(checkTransaction); } // Always ensure a transaction close, even if we have an exception. // Notify the Composite that this transaction has closed. TableSystem.CloseTransaction(Transaction); } catch (Exception) { // TODO: notify the error } finally { Done = true; } } } return(changedTablesList.ToArray()); }
private void CheckConflicts(IEnumerable <ObjectCommitState> namespaceJournals) { AssertNoDirtySelect(); // Check there isn't a namespace clash with database objects. // We need to create a list of all create and drop activity in the // Composite from when the transaction started. var allDroppedObs = new List <ObjectName>(); var allCreatedObs = new List <ObjectName>(); foreach (var nsJournal in namespaceJournals) { if (nsJournal.CommitId >= Id) { allDroppedObs.AddRange(nsJournal.DroppedObjects); allCreatedObs.AddRange(nsJournal.CreatedObjects); } } // The list of all dropped objects since this transaction // began. bool conflict5 = false; ObjectName conflictName = null; string conflictDesc = ""; foreach (ObjectName droppedOb in allDroppedObs) { if (ObjectsDropped.Contains(droppedOb)) { conflict5 = true; conflictName = droppedOb; conflictDesc = "dropped"; } } // The list of all created objects since this transaction // began. foreach (ObjectName createdOb in allCreatedObs) { if (ObjectsCreated.Contains(createdOb)) { conflict5 = true; conflictName = createdOb; conflictDesc = "created"; } } if (conflict5) { // Namespace conflict... throw new ObjectDuplicatedConflictException(conflictName, conflictDesc); } // For each journal, foreach (var changeJournal in ChangedTables) { // The table the change was made to. int tableId = changeJournal.TableId; // Get the master table with this table id. TableSource master = TableSystem.GetTableSource(tableId); // True if the state contains a committed resource with the given name bool committedResource = TableSystem.ContainsVisibleResource(tableId); // Check this table is still in the committed tables list. if (!CreatedTables.Contains(tableId) && !committedResource) { // This table is no longer a committed table, so rollback throw new NonCommittedConflictException(master.TableInfo.TableName); } // Since this journal was created, check to see if any changes to the // tables have been committed since. // This will return all journals on the table with the same commit_id // or greater. var journalsSince = master.FindChangesSinceCommit(Id); // For each journal, determine if there's any clashes. foreach (var tableJournal in journalsSince) { // This will thrown an exception if a commit classes. if (changeJournal.TestCommitClash(tableJournal, out var conflict)) { throw new RowRemoveConflictException(master.TableName, conflict.RowId); } } } // Look at the transaction journal, if a table is dropped that has // journal entries since the last commit then we have an exception // case. foreach (int tableId in DroppedTables) { // Get the master table with this table id. TableSource master = TableSystem.GetTableSource(tableId); // Any journal entries made to this dropped table? if (master.FindChangesSinceCommit(Id).Any()) { // Oops, yes, rollback! throw new DroppedModifiedObjectConflictException(master.TableInfo.TableName); } } }