0% found this document useful (0 votes)
3 views

Lecture 05.7 SQL Transactions and Concurrency Management_26

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Lecture 05.7 SQL Transactions and Concurrency Management_26

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

Managing transactions

and concurrency
TRANSACTION MANAGEMENT AND CONCURRENCY

1 / 27
Transaction
Management
Refer Joel Murach, Murach’s MySQL, 2nd Edition, 2015, ISBN-13: 978-1890774820

Murach's MySQL, C13 © 2015, MIKE MURACH & ASSOCIATES, INC. 2 / 27


Transactions in mySQL
• A transaction is a group of SQL statements that you combine into a single logical unit of work
• By combining SQL statements like this, you can prevent certain kinds of database errors
• NOTE: Some storage engines don’t support transactions. MyISAM storage engine doesn’t support
transactions. InnoDB is a MySQL storage engine that supports transactions.
• How to commit and rollback transactions
• By default, a MySQL session uses autocommit mode, which automatically commits INSERT, UPDATE,
and DELETE statements immediately after you execute them
• If the START TRANSACTION statement is used, it identifies the start of the transaction, which
temporarily turns off autocommit mode
• Multiple SQL statements such as SELECT, INSERT, UPDATE or DELETE are then used
• Based on certain conditions (usually error free conditions), COMMIT statement is used to commit the changes to the
database, which makes the changes permanent.
• Otherwise, the ROLLBACK statement is used to roll back the changes, which cancels them.
• When to use transactions
• When you code two or more INSERT, UPDATE, or DELETE statements that affect related data
• When you move rows from one table to another table by using INSERT and DELETE statements
• Whenever the failure of an INSERT, UPDATE, or DELETE statement would violate data integrity
• MySQL automatically commits changes after a DDL statement such as a CREATE TABLE statement.
• As a result, you shouldn’t code a DDL statement within a transaction unless you want to commit the
changes and end the transaction.
3 / 27
Example: Transactions
DELIMITER //
CREATE PROCEDURE test()
BEGIN
DECLARE sql_error TINYINT DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
SET sql_error = TRUE;

START TRANSACTION;

INSERT INTO invoices VALUES (115, 34, 'ZXA-080', '2015-01-18', 14092.59, 0, 0, 3, '2015-04-18', NULL);
INSERT INTO invoice_line_items VALUES (115, 1, 160, 4447.23, 'HW upgrade');
INSERT INTO invoice_line_items VALUES (115, 2, 167, 9645.36, 'OS upgrade');
IF sql_error = FALSE
THEN COMMIT;
SELECT 'The transaction was committed.';
ELSE
ROLLBACK;
SELECT 'The transaction was rolled back.’;
END IF;
END//
4 / 27
SAVEPOINT to Manage Transactions
• Save points can be used to roll back a
transaction to the beginning of the transaction => INSERT INTO product_key VALUES (AAA);
or to a particular save point => SAVEPOINT my_savepoint;
• You can use the SAVEPOINT statement to create a
save point with the specified name => INSERT INTO product_key VALUES (BBB);
• You can use the ROLLBACK TO SAVEPOINT => INSERT INTO product_key VALUES (CCC);
statement to roll back a transaction to the => ROLLBACK TO SAVEPOINT my_savepoint;
specified save point
=> INSERT INTO product_key VALUES (DDD);
• Save points are useful when a single transaction => COMMIT;
contains so many SQL statements that rolling
back the entire transaction would be inefficient
This rolls back the values BBB and CCC that
• In that case, an application can roll back to the
last save point before an error occurred. were entered after the savepoint, my_savepoint,
• Then, the appropriate processing can be done was established.
from there. Only the values AAA and DDD are inserted at
• For most applications, though, you won’t need to commit.
use save points.

5 / 27
Save point – a depiction in time
Pgm A Pgm B Pgm C Pgm D

(
(

(
(

(
Save Point

(
(

(
Save Point

(
(

(
(

Save Point

(
(
6 / 27
CONCURRENCY AND LOCKING
• When two or more users have access to the same database, it’s possible for them to be
working with the same data at the same time - this is called concurrency
• Most database systems provide ability to support two or more transactions that are working with the
same data at the same time

• Concurrency is a problem only when the data is being modified


• When two or more SELECT statements read the same data, the SELECT statements don’t affect each
other
• Although concurrency isn’t a problem when two users retrieve the same data at the same time, it can
become a problem when one user updates data that other users are also viewing or updating

• MySQL can automatically prevent some concurrency problems by using locks


• A lock stops the execution of another transaction if it conflicts with a transaction that is already
running

7 / 27
Example: Concurrent Transactions
Two transactions that retrieve and then modify the data in the same row
Transaction A Transaction B

START TRANSACTION;
UPDATE invoices SET credit_total =
--Use a second connection to execute these
credit_total + 100 WHERE invoice_id = statements! --Otherwise, they might not work
6;
as described.
START TRANSACTION;
Waits
--the SELECT statement in Transaction B
won't show the updated data --the T SELECT invoice_id, credit_total FROM
UPDATE statement in Transaction B will invoices WHERE invoice_id = 6;
wait for transaction A to finish i
m UPDATE invoices SET credit_total =
COMMIT;
e credit_total + 200 WHERE invoice_id = 6;
--the SELECT statement in Transaction B
will display the updated data --the COMMIT;
UPDATE statement in Transaction B will
execute immediately

8 / 27
Example: Concurrent Transactions
Two transactions that retrieve and then modify the data in the same row

Consider two concurrent transactions: Transaction A and Transaction B


START TRANSACTION; // Transaction A
START TRANSACTION; // Transaction B • Assume that each statement executes in the sequence shown
• The UPDATE statement in Transaction A will execute
UPDATE invoices SET credit_total =
credit_total + 100 WHERE invoice_id = 6; immediately
• The SELECT statement in Transaction B won't show the
SELECT invoice_id, credit_total FROM
invoices WHERE invoice_id = 6;
updated data

COMMIT; • Use a second connection to execute these statements!


UPDATE invoices SET credit_total = • The SELECT statement in Transaction B will display the updated
credit_total + 200 WHERE invoice_id = 6; data
• The UPDATE statement in Transaction B will wait for
COMMIT;
transaction A to finish

9 / 27
Four Types of Concurrency Problems
• In a large system with many users, you should expect for
these kinds of problems to occur. In general, you don’t
need to take any action except to anticipate the
problem. In many cases, if the SQL statement is
resubmitted, the problem goes away.

• On some systems, if two transactions overwrite each


other, the validity of the database is compromised and
resubmitting one of the transactions won’t eliminate
the problem. If you’re working on such a system, you
must anticipate these concurrency problems and
account for them in your code.

• If one of these problems could affect the data integrity of


your system, you can change the default locking behavior
by setting the transaction isolation level

10 / 27
Lost update
1. Transaction 1 reads the items in
stock for laptops which is 12. A little
later transaction 2 reads the value
for ItemsinStock for laptops which
will still be 12 at this point of time.
Transaction 2 then sells three
laptops, shortly before transaction 1
sells 2 items.
2. Transaction 2 will then complete its
execution first and update
ItemsinStock to 9 since it sold three
of the 12 laptops. Transaction 1
commits itself. Since transaction 1
sold two items, it updates
ItemsinStock to 10.
3. This is incorrect, the correct figure is
Update is lost 12-3-2 = 7
Courtesy : CodingInsigt.com

11 / 27
Dirty read 1. Transaction 1 will perform the purchase task for
the user. The first step in the transaction will be
to update the ItemsinStock.
ItemsinStock = 12
2. Before the transaction, there are 12 items in the
stock; the transaction will update this to 11. The
transaction will now communicate with an
external billing gateway.

3. If at this point in time, another transaction, let’s


say Transaction 2, reads ItemsInStock for laptops,
it will read 11. However, if subsequently, the user
behind Transaction 1 turns out to have
insufficient funds in his account, Transaction 1
Will become will be rolled back and the value for ItemsInStock
Dirty Read column will revert to 12.

4. However, Transaction 2 has 11 as the value for


ItemsInStock column. This is dirty data and the
problem is called dirty read problem.
Courtesy : CodingInsigt.com

12 / 27
Non repeatable reads

1. Alice and Bob start two


database transactions.
2. Bob reads the post record
and title column value is
Transactions.
3. Alice modifies the title of a
given post record to the
value of ACID.
4. Alice commits her database
transaction.
5. If Bob’s re-reads the post
record, he will observe a
different version of this
table row.
Non
repeatable
Courtesy : vladmihalcea.com

13 / 27
Phantom Reads Courtesy : vladmihalcea.com
1. Alice and Bob start two
database transactions.
2. Bob’s reads all the
post_comment records
associated with the post
row with the identifier value
of 1.
3. Alice adds a new
post_comment record
which is associated with the
post row having the
identifier value of 1.
4. Alice commits her database
transaction.
5. If Bob’s re-reads the
post_comment records
having the post_id column
value equal to 1, he will
Phantom observe a different version
Read of this result set.
Courtesy : vladmihalcea.com

14 / 27
Changing Locking Behavior to Prevent
Concurrency Problems
• The transaction isolation level controls the degree to which transactions are isolated from one another. At the
more restrictive isolation levels, concurrency problems are reduced or eliminated. However, at the least
restrictive levels, performance is enhanced.
• To change the transaction isolation level, you use the SET TRANSACTION ISOLATION LEVEL statement.
• If you include the GLOBAL keyword, the isolation level is set globally for all new transactions in all sessions. If
you include the SESSION keyword, the isolation level is set for all new transactions in the current session. If you
omit both GLOBAL and SESSION, the isolation level is set for the next new transaction in the current session.
• The default transaction isolation level is REPEATABLE READ. This level places locks on all data that’s used in a
transaction, preventing other users from updating that data. However, this isolation level still allows inserts, so
phantom reads can occur.
• The READ UNCOMMITTED isolation level doesn’t set any locks and ignores locks that are already held. This level
results in the highest possible performance for your query, but at the risk of every kind of concurrency problem.
For this reason, you should only use this level for data that is rarely updated.
• The READ COMMITTED isolation level locks data that has been changed but not committed. This prevents dirty
reads but allows all other types of concurrency problems.
• The SERIALIZABLE isolation level places a lock on all data that’s used in a transaction. Since each transaction
must wait for the previous transaction to commit, the transactions are handled in sequence. This is the most
restrictive isolation level.

15 / 27
Changing Locking Behavior to Prevent Concurrency Problems

16 / 27
Optimistic locking versus pessimistic locking

Courtesy : vladmihalcea.com

17 / 27
Optimistic locking versus pessimistic locking

Courtesy : vladmihalcea.com

18 / 27
Deadlock or “deadly embrace”
Alice Database Bob
Begin Transaction
Begin Transaction
Update Product ID = 12

Update Customer ID = 24

Update Product ID = 12

Update Customer ID = 24

Courtesy : vladmihalcea.com

19 / 27
Preventing Deadlocks
• A deadlock occurs when neither of two transactions can be committed because each has a lock
on a resource needed by the other transaction.
UPDATE statements that illustrate deadlocking
Transaction A
START TRANSACTION; How to prevent deadlocks
UPDATE savings SET balance = balance - transfer_amount;
UPDATE checking SET balance = balance + transfer_amount; • Don’t allow transactions to remain open for very long.
COMMIT;
• Don’t use a transaction isolation level higher than necessary.
Transaction B (possible deadlock)
START TRANSACTION;
• Make large changes when you can be assured of nearly exclusive
UPDATE checking SET balance = balance - transfer_amount; access.
UPDATE savings SET balance = balance + transfer_amount;
COMMIT;
• Consider locking when coding your transactions.
Transaction B (prevents deadlocks) • Revisit the sequence of your transactions.
START TRANSACTION;
UPDATE savings SET balance = balance + transfer_amount;
UPDATE checking SET balance = balance - transfer_amount;
COMMIT;

20 / 27
Prevent Deadlocks, contd…
• Don’t allow transactions to remain open for very long
• Keep transactions short
• Keep SELECT statements outside of the transaction except when absolutely necessary.
• Never code requests for user input during a transaction.

• Don’t use a transaction isolation level higher than necessary


• The default level of REPEATABLE READ is usually acceptable, but you should consider changing to READ COMMITTED if
deadlocks become a problem.
• Reserve the use of the SERIALIZABLE level for short transactions that make changes to data where integrity is vital.

• Make large changes when you can be assured of nearly exclusive access
• If you need to change millions of rows in an active table, don’t do so during hours of peak usage.
• If possible, give yourself exclusive access to the database before making large changes.

• Take locking behavior into consideration when coding your transactions


• If you need to code two or more transactions that update the same resources, code the updates in the same order in each
transaction.

21 / 27
Distributed transactions – Problem?
A monolithic system decomposed into self-encapsulated services, it can break transactions.
This means a local transaction in the monolithic system is now distributed into multiple services that will
be called in a sequence.

• In the example here, a user sends a Put


Order action to a monolithic system.
• The system creates a local database Monolithic
transaction that works over multiple
database tables.
• If any step fails, the transaction can roll
back.
• This is known as ACID (Atomicity,
Consistency, Isolation, Durability), which
is guaranteed by the database system.

Courtesy: developers.redhat.com

22 / 27
Distributed transactions – Problem? Contd..
A monolithic system decomposed into self-encapsulated services, it can break transactions.
This means a local transaction in the monolithic system is now distributed into multiple services that will
be called in a sequence.

• Same is decomposed, as MicroServices.


• Both the CustomerMicroservice and the
What if this
OrderMicroservice, can have separate
fails?
databases.
• The microservice-based system does
not have a global transaction
coordinator by default. X
• In the example here, if the
CreateOrder method fails, how do we
roll back the changes we applied by
the CustomerMicroservice?

Courtesy: developers.redhat.com

23 / 27
Distributed transactions – 2 Phase Commit – A solution
• When the user sends a put order request, the
Coordinator first creates a global transaction with all
the context information.
• It will then tell CustomerMicroservice to prepare for
updating a customer fund with the created
transaction.
• The CustomerMicroservice will then check, for
example, if the customer has enough funds to
proceed with the transaction.
• Once CustomerMicroservice is OK to perform the
change, it will lock down the object from further
changes and tell the Coordinator that it is prepared.
• The same thing happens while creating the order in
the OrderMicroservice.
• Once the Coordinator has confirmed all microservices
are ready to apply their changes, it will then ask them
to apply their changes by requesting a commit with
the transaction.
• At this point, all objects will be unlocked. Courtesy: developers.redhat.com

24 / 27
Distributed transactions – 2 Phase Commit – A solution

• If at any point a single microservice fails to


prepare, the Coordinator will abort the
transaction and begin the rollback process.
• In the example here, the CustomerMicroservice
failed to prepare for some reason, but the
OrderMicroservice has replied that it is
prepared to create the order.
• The Coordinator will request an abort on the
OrderMicroservice with the transaction and the
OrderMicroservice will then roll back any
changes made and unlock the database objects
• Industry Standard – XA (eXtended Architecture)
Compliance
• https://en.wikipedia.org/wiki/X/Open_XA

Courtesy: developers.redhat.com

25 / 27
Distributed transactions – Saga Pattern– Another solution

• It is different from 2pc, which is synchronous.


• The Saga pattern is asynchronous and reactive.
• In a Saga pattern, the distributed transaction is
fulfilled by asynchronous local transactions on
all related microservices. The microservices
communicate with each other through an event
bus.
• In the example here, the OrderMicroservice
receives a request to place an order.
• It first starts a local transaction to create an
order and then emits an OrderCreated event.
• The CustomerMicroservice listens for this event
and updates a customer fund once the event is
received.
• If a deduction is successfully made from a fund,
a CustomerFundUpdated event will then be
emitted, which in this example means the end
of the transaction.

26 / 27
Distributed transactions – Saga Pattern– Another solution

• If any microservice fails to complete its local


transaction, the other microservices will run
compensation transactions to roll back the
changes.
• Here is a diagram of the Saga pattern for a
compensation transaction
• In the example here, the UpdateCustomerFund
failed for some reason, and it then emitted a
CustomerFundUpdateFailed event.
• The OrderMicroservice listens for the event and
start its compensation transaction to revert the
order that was created..

27 / 27

You might also like