18 using System.Collections.Generic;
19 using System.ComponentModel;
27 namespace Deveel.Data.Transactions {
33 public IEnumerable<ITableSource> SelectedFromTables {
get;
private set; }
36 Composite = composite;
38 SelectedFromTables = selectedFromTables;
44 ChangedTables = touchedTables.Select(t => t.EventRegistry).Where(tableJournal => tableJournal.EventCount > 0);
63 public IEnumerable<int> CreatedTables {
get;
private set; }
65 public IEnumerable<int> DroppedTables {
get;
private set; }
67 public IEnumerable<int> ConstraintAlteredTables {
get;
private set; }
69 public IEnumerable<TableEventRegistry> ChangedTables {
get;
private set; }
71 public IEnumerable<ObjectName> ObjectsCreated {
get;
private set; }
73 public IEnumerable<ObjectName> ObjectsDropped {
get;
private set; }
75 public bool Done {
get;
private set; }
77 public long CommitId {
get;
private set; }
79 public bool HasChanges {
80 get {
return CreatedTables.Any() || DroppedTables.Any() || ConstraintAlteredTables.Any() || ChangedTables.Any(); }
91 return list.Any(info => info.Master.Equals(master));
100 foreach (
TableSource selectedTable
in SelectedFromTables) {
104 if (journalsSince.Any()) {
109 "Concurrent Serializable Transaction Conflict(4): " +
110 "Select from table that has committed changes: " +
117 internal void CheckConflicts(IEnumerable<TransactionObjectState> namespaceJournals) {
118 AssertNoDirtySelect();
123 var allDroppedObs =
new List<ObjectName>();
124 var allCreatedObs =
new List<ObjectName>();
125 foreach (var nsJournal
in namespaceJournals) {
126 if (nsJournal.CommitId >= CommitId) {
127 allDroppedObs.AddRange(nsJournal.DroppedObjects);
128 allCreatedObs.AddRange(nsJournal.CreatedObjects);
134 bool conflict5 =
false;
135 object conflictName = null;
136 string conflictDesc =
"";
137 foreach (
ObjectName droppedOb
in allDroppedObs) {
138 if (ObjectsDropped.Contains(droppedOb)) {
140 conflictName = droppedOb;
141 conflictDesc =
"Drop Clash";
146 foreach (
ObjectName createdOb
in allCreatedObs) {
147 if (ObjectsCreated.Contains(createdOb)) {
149 conflictName = createdOb;
150 conflictDesc =
"Create Clash";
157 "Concurrent Serializable Transaction Conflict(5): " +
158 "Namespace conflict: " + conflictName +
" " +
165 int tableId = changeJournal.
TableId;
167 TableSource master = Composite.GetTableSource(tableId);
170 bool committedResource = Composite.ContainsVisibleResource(tableId);
173 if (!CreatedTables.Contains(tableId) && !committedResource) {
177 "Concurrent Serializable Transaction Conflict(2): " +
178 "Table altered/dropped: " + master.
TableName);
197 foreach (
int tableId
in DroppedTables) {
199 TableSource master = Composite.GetTableSource(tableId);
205 "Concurrent Serializable Transaction Conflict(3): " +
206 "Dropped table has modifications: " + master.
TableName);
217 var normalizedChangedTables =
new List<CommitTableInfo>(8);
221 normalizedChangedTables.AddRange(
222 ChangedTables.Select(tableJournal =>
new { tableJournal, tableId = tableJournal.TableId })
223 .Where(t => !DroppedTables.Contains(t.tableId))
224 .Select(t =>
new { t, masterTable = Composite.GetTableSource(t.tableId) })
226 Master = t.masterTable,
227 Journal = t.t.tableJournal,
228 ChangesSinceCommit = t.masterTable.FindChangesSinceCmmit(CommitId).ToArray()
232 foreach (var tableId
in CreatedTables) {
235 if (!DroppedTables.Contains(tableId)) {
236 TableSource masterTable = Composite.GetTableSource(tableId);
237 if (!CommitTableListContains(normalizedChangedTables, masterTable)) {
244 normalizedChangedTables.Add(tableInfo);
249 return normalizedChangedTables.ToArray();
258 var normalizedDroppedTables =
new List<TableSource>(8);
259 foreach (var tableId
in DroppedTables) {
262 if (!CreatedTables.Contains(tableId)) {
263 TableSource masterTable = Composite.GetTableSource(tableId);
264 normalizedDroppedTables.Add(masterTable);
268 return normalizedDroppedTables.ToArray();
272 var changedTableSource =
new ITable[normalizedChangedTables.Length];
275 for (
int i = 0; i < normalizedChangedTables.Length; ++i) {
284 if (allTableChanges == null || allTableChanges.Length == 0) {
293 mtable.FlushIndexes();
297 checkTransaction.UpdateVisibleTable(tableInfo.
Master, tableInfo.
IndexSet);
312 tableInfo.
IndexSet = checkTransaction.GetIndexSetForTable(master);
314 mtable.FlushIndexes();
321 changedTableSource[i] = checkTransaction.GetTable(master.
TableName);
324 return changedTableSource;
328 if (commitActions == null)
331 foreach (var tableInfo
in normalizedChangedTables) {
334 if (changeJournal != null) {
336 var tableName = tableInfo.Master.TableName;
337 commitActions(
new TableCommitInfo(checkTransaction.CommitId, tableName, tableInfo.NormalizedAddedRows,
338 tableInfo.NormalizedAddedRows));
346 foreach (var tableId
in ConstraintAlteredTables) {
349 for (
int n = 0; n < normalizedChangedTables.Length; ++n) {
352 checkTransaction.CheckAddConstraintViolations(changedTableSource[n],
ConstraintDeferrability.InitiallyDeferred);
363 for (
int i = 0; i < normalizedChangedTables.Length; ++i) {
367 if (changeJournal != null) {
369 int[] normalizedRemovedRows = changeJournal.
RemovedRows.ToArray();
372 checkTransaction.CheckRemoveConstraintViolations(changedTableSource[i], normalizedRemovedRows,
ConstraintDeferrability.InitiallyDeferred);
375 int[] normalizedAddedRows = changeJournal.
AddedRows.ToArray();
378 checkTransaction.CheckAddConstraintViolations(changedTableSource[i], normalizedAddedRows,
ConstraintDeferrability.InitiallyDeferred);
388 internal IEnumerable<TableSource>
Commit(IList<TransactionObjectState> nameSpaceJournals, Action<TableCommitInfo> commitActions) {
389 var changedTablesList =
new List<TableSource>();
395 bool entriesCommitted =
false;
399 CheckConflicts(nameSpaceJournals);
405 var normalizedChangedTables = GetNormalizedChangedTables();
406 var normalizedDroppedTables = GetNormalizedDroppedTables();
434 checkTransaction = Composite.CreateTransaction(
IsolationLevel.Serializable);
441 foreach (
TableSource masterTable
in normalizedDroppedTables) {
443 checkTransaction.RemoveVisibleTable(masterTable);
449 var changedTableSource = FindChangedTables(checkTransaction, normalizedChangedTables);
454 checkTransaction.ReadOnly(
true);
456 CheckConstraintViolations(checkTransaction, normalizedChangedTables, changedTableSource);
459 FireChangeEvents(checkTransaction, normalizedChangedTables, commitActions);
477 entriesCommitted =
true;
483 if (changeJournal != null) {
491 changedTablesList.Add(master);
496 if (CreatedTables.Any() || DroppedTables.Any()) {
499 Composite.CommitToTables(CreatedTables, DroppedTables);
503 if (ObjectsCreated.Any() || ObjectsDropped.Any()) {
511 if (entriesCommitted ==
false) {
515 int tableId = changeJournal.
TableId;
517 TableSource master = Composite.GetTableSource(tableId);
527 if (checkTransaction != null) {
528 checkTransaction.Dispose();
529 Composite.CloseTransaction(checkTransaction);
534 }
catch (Exception) {
542 return changedTablesList.ToArray();
TableSource[] GetNormalizedDroppedTables()
static bool CommitTableListContains(IEnumerable< CommitTableInfo > list, TableSource master)
Returns true if the given List of CommitTableInfo objects contains an entry for the given master tabl...
A static container class for information collected about a table during the commit cycle...
Defines the contract to access the data contained into a table of a database.
IEnumerable< int > RemovedRows
void FireChangeEvents(ITransaction checkTransaction, CommitTableInfo[] normalizedChangedTables, Action< TableCommitInfo > commitActions)
The system implementation of a transaction model that handles isolated operations within a database c...
TableEventRegistry Journal
IEnumerable< TableEventRegistry > FindChangesSinceCmmit(long commitId)
int[] NormalizedAddedRows
IEnumerable< int > TablesConstraintAltered
Describes the name of an object within a database.
IEnumerable< int > TablesCreated
ConstraintDeferrability
The type of deferrance of a constraint.
IEnumerable< TableSource > Commit(IList< TransactionObjectState > nameSpaceJournals, Action< TableCommitInfo > commitActions)
IMutableTable CreateTableAtCommit(ITransaction transaction)
void RollbackTransactionChange(TableEventRegistry registry)
void TestCommitClash(TableInfo tableInfo, TableEventRegistry journal)
TransactionRegistry Registry
CommitTableInfo[] GetNormalizedChangedTables()
TransactionWork(TableSourceComposite composite, Transaction transaction, IEnumerable< ITableSource > selectedFromTables, IEnumerable< IMutableTable > touchedTables, TransactionRegistry journal)
An object that access to a set of indexes.
const int TableRemoveClash
ITable[] FindChangedTables(ITransaction checkTransaction, CommitTableInfo[] normalizedChangedTables)
IEnumerable< ObjectName > ObjectsCreated
int[] NormalizedRemovedRows
void AssertNoDirtySelect()
void CheckConflicts(IEnumerable< TransactionObjectState > namespaceJournals)
TableEventRegistry[] ChangesSinceCommit
IEnumerable< ObjectName > ObjectsDropped
IEnumerable< int > AddedRows
The simplest implementation of a transaction.
void CommitTransactionChange(int commitId, TableEventRegistry change, IIndexSet indexSet)
void CheckConstraintViolations(ITransaction checkTransaction, CommitTableInfo[] normalizedChangedTables, ITable[] changedTableSource)
IEnumerable< int > TablesDropped