1# Merge Transactions in Project:M36
5Common database management systems offer one transaction "stream" whereby multiple database users are simultaneously contending for commits to access or change a single database state. Database management systems implement complex locking and caching in order to simulate concurrent access to this state.
7Project:M36 allows for user-defined named "heads" which represent states (branches) onto which users can tack on additional transactions. This feature enables:
9* experimental changes which may or may not be merged back to the main state of the database
10* reduced contention over a single head
11* genuinely transaction-safe DDL (schema definition changes) without locking, caveats, or abstraction leaks
12* merge transactions according to business logic
13* elimination of "serialization errors"
15Programmers are likely familiar with this workflow since this behavior is analogous to source version control branching and merging. Project:M36 uses terminology from [git version control](https://git-scm.com/).
21|:branch <branch name>|Create a new branch.|
22|:jumphead <head name>|Jump to the named head.|
23|:jump <transaction id>|Jump to an arbitrarily-identified transaction. This allows the session's context to travel back in time to a part of the graph which is not a head.|
24|:showgraph|Display the transaction graph as a relation.|
25|:mergetrans <merge strategy> <branchA> <branchB>|Merge one branch onto another. This requires that the current context is on one of the heads. The "merge strategy" is one of "union", "unionpreferbranch <branch name>" , or "selectedbranch".|
29### Selected Branch Merge
31The naivest merge strategy is to pull in the database context of one branch while discarding the context of a second branch. This merge strategy is useful for marking the end of an experimental branch that is to be considered discarded or a dead end. This merge strategy always succeeds.
35The union merge strategy attempts to merge the components of the two branches' database contexts. These components are:
37* inclusion dependencies (constraints)
43If both branches have a atom function, etc. of the same name, then the merge fails with an unresolvable conflict.
45As a special case for relation variables, if both branches have a relation variable of the same name and type (same attributes), then the resultant merged relation variable is a union of both branches' relation variables.
47### Union Prefer Branch Merge
49The union-prefer-branch merge is identical to union merge except that, when encountering a conflict case as described above, the strategy chooses a component from the preferred branch. Thus, this merge strategy always succeeds.
51## Additional Strategies
53Project:M36 will support more complex merge strategies in the future. In particular, business logic will likely dictate that Project:M36 support user-defined strategies, though this is not yet supported.
57Branching and merging are built-in to the Project:M36 ```tutd``` client.
59First, let's create a new branch for some new sales data.
61TutorialD (master/main): :branch add_sales_feature
62TutorialD (add_sales_feature):
65Note how the name in parentheses changes as we create and implicitly jump to the new "add_sales_feature" branch.
67Next, we will add the sales data.
70TutorialD (add_sales_feature): sales := relation{tuple{amount 45, product "peanuts"},tuple{amount 20, product "onions"}}
71TutorialD (add_sales_feature): :showexpr sales
72┌───────────┬─────────────┐
73│amount::Int│product::Text│
74├───────────┼─────────────┤
77└───────────┴─────────────┘
78TutorialD (add_sales_feature): :commit
81Now, the relation variable "sales" is available on the "add_sales_feature" branch, but *not* the "master" branch. Let's verify this.
84TutorialD (add_sales_feature): :jumphead master
85TutorialD (master/main): :showexpr sales
86ERR: RelVarNotDefinedError "sales"
89Now that we are on the "master" branch, let's add a relation variables unrelated to sales.
92TutorialD (master/main): employees := relation{tuple{name "Steve"},tuple{name "Cindy"}}
93TutorialD (master/main): :commit
96Note that the "employees" relation variable is only available on the "master" branch and not on the "add_sales_feature" branch.
98Let's look at the transaction graph:
101TutorialD (master/main): :showgraph
102┌─────────────┬───────────────────┬──────────────────────────────────────┬────────────────────────────────────────┐
103│current::Bool│head::Text │id::Text │parents::relation {id::Text} │
104├─────────────┼───────────────────┼──────────────────────────────────────┼────────────────────────────────────────┤
105│False │"" │"0d3bf914-1695-4f95-ab93-6c543d7b3dfa"│┌──────────────────────────────────────┐│
107│ │ │ │├──────────────────────────────────────┤│
108│ │ │ ││"0e51d95b-5578-4190-802b-9ef280a7f386"││
109│ │ │ │└──────────────────────────────────────┘│
110│False │"add_sales_feature"│"8b4d4eaf-31a3-4e48-85d3-bf6e8ac101ea"│┌──────────────────────────────────────┐│
112│ │ │ │├──────────────────────────────────────┤│
113│ │ │ ││"0d3bf914-1695-4f95-ab93-6c543d7b3dfa"││
114│ │ │ │└──────────────────────────────────────┘│
115│False │"" │"0e51d95b-5578-4190-802b-9ef280a7f386"│┌────────┐ │
118│True │"master" │"e4228cb8-e792-48c9-b987-7d78fb1abe04"│┌──────────────────────────────────────┐│
120│ │ │ │├──────────────────────────────────────┤│
121│ │ │ ││"0e51d95b-5578-4190-802b-9ef280a7f386"││
122│ │ │ │└──────────────────────────────────────┘│
123└─────────────┴───────────────────┴──────────────────────────────────────┴────────────────────────────────────────┘
127```:showgraph``` shows us which database context is "current" and which parents are linked to each transaction.
129Now, imagine that the work on the "add_sales_merge" branch is complete, so we will merge the "add_sales_feature" branch back into the "master" branch. We say we are merging "back" because both branches share a common ancestor transaction.
132TutorialD (master/main): :mergetrans union add_sales_feature master
133TutorialD (master/main): :showexpr employees
140TutorialD (master/main): :showexpr sales
141┌───────────┬─────────────┐
142│amount::Int│product::Text│
143├───────────┼─────────────┤
146└───────────┴─────────────┘
149After the merge, both relation variables appear in resultant merged transaction. This is because we used a "union merge strategy" which tries to mash both database contexts together.
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list