You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A9: Main accesses to the database and transactions
This artefact shows the main accesses to the database, as well as the transactions necessary for ensuring database consistency.
For each transaction, the isolation level is explicitly stated and read-only transactions are identified to improve global performance. For each identified access, the SQL code and the reference of web resources (A7) are provided.
1. Main Accesses
This section describes the main accesses to the database.
SELECT*FROM questions
WHERE
tstitle @@ plainto_tsquery('english', $search_query)
ORDER BY
ts_rank(tstitle, plainto_tsquery('english', $search_query))
DESC;
The tstitle column is of type "tsvector", and is equal to to_tsvector('english', title), as advised in class.
This column is kept consistent with the title by updating it with triggers "on insert" and "on update".
Transactions needed to assure the integrity of the data.
T01
Insert a question
Justification
Since a object-oriented approach was used to map the question UML subclass to the relational model, atomicity must be guaranteed so all classes that need to be inserted are in fact all or none inserted.
Isolation level
Read Uncommitted
BEGIN TRANSACTION;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
DO $$
DECLARE
new_id INTEGER;
BEGININSERT INTO messages (author) VALUES ($author) RETURNING id INTO new_id;
INSERT INTO commentables (id) VALUES (new_id);
INSERT INTO questions (id, title) VALUES (new_id, $title);
INSERT INTO message_versions (content, message_id) values ($content, new_id);
END $$;
COMMIT;
T02
Insert an answer
Justification
Since a object-oriented approach was used to map the answer UML subclass to the relational model, atomicity must be guaranteed so all classes that need to be inserted are in fact all or none inserted.
Isolation level
Read Uncommitted
BEGIN TRANSACTION;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
DO $$
DECLARE
new_id INTEGER;
BEGININSERT INTO messages (author) VALUES ($author) RETURNING id INTO new_id;
INSERT INTO commentables (id) VALUES (new_id);
INSERT INTO answers (id, question_id) VALUES (new_id, $question);
INSERT INTO message_versions (content, message_id) values ($content, new_id);
END $$;
COMMIT;
T03
Insert a comment
Justification
Since a object-oriented approach was used to map the comment UML subclass to the relational model, atomicity must be guaranteed so all classes that need to be inserted are in fact all or none inserted.
Isolation level
Read Uncommitted
BEGIN TRANSACTION;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
DO $$
DECLARE
new_id INTEGER;
BEGININSERT INTO messages (author) VALUES ($author) RETURNING id INTO new_id;
INSERT INTO comments (id, commentable_id) VALUES (new_id, $commentable);
INSERT INTO message_versions (content, message_id) values ($content, new_id);
END $$;
COMMIT;
Several other user stories would require the use of transactions. Fortunately, by default all statements like insert, update or delete are inside their own transaction and the triggers that are fired by them also run in the same transaction. Therefore if anything fails in the execution of the trigger, then everything is rolled back, including the initial statement that fired the trigger.
We've made extensive use of this autocommit mode to ensure database integrity. For example, when a vote is made to a message, a trigger updates its score value. If these two actions weren't executed inside the same transaction and there was a failure in updating the score attribute, then the number of positive votes minus the negative ones wouldn't match the score, leaving the database in a inconsistent state.
This is true for all derived attributes, whose consistency is ensured by triggers.
In this example the trigger TRIGGER06 can be replaced by the following transaction:
BEGIN TRANSACTION;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
INSER INTO votes (message_id, user_id, positive)
values ($message_id, $user_id, $positive);
IF $positive THEN
UPDATE messages
SET score = score +1WHERE $message_id =messages.id;
ELSIF NOT $positive THEN
UPDATE messages
SET score = score -1WHERE $message_id =messages.id;
END IF;
COMMIT;
Revision history
01/05/2018: Added links to resources.
02/05/2018: Added example transaction that would be needed if triggers weren't run in the same transaction as the statement which fired it.