Quantcast
Channel: Question and Answer » transaction
Viewing all articles
Browse latest Browse all 35

Mysql transaction READ REPEATABLE and READ COMMITTED read view

$
0
0

I’ve come across something strage using Amazon RDS (MySQL 5.6.23).

I had issues when concurrent transactions were locking and then calculating a value from multiple tables. The following is a quick demo of what was happening when using transactions with isolation level REPEATABLE READ.

+------+-----------------------------------------------+-----------------------------------------------+
| Time | first transaction                             | second transaction                            |
+------+-----------------------------------------------+-----------------------------------------------+
| 1    | START TRANSACTION;                            | START TRANSACTION;                            |
|      |                                               |                                               |
| 2    | SELECT * FROM stock WHERE sku=SKU0 FOR UPDATE | SELECT * FROM stock WHERE sku=SKU0 FOR UPDATE |
|      |                                               |                                               |
| 3    | [GOT THE LOCK]                                | [WAIT]                                        |
|      |                                               |                                               |
| 4    | SELECT s.qty - COUNT(r.fk_stock) AS qty       |                                               |
|      |   FROM stock s                                |                                               |
|      |   LEFT JOIN reservation r                     | [WAIT]                                        |
|      |   WHERE s.sku = SKU0                          |                                               |
|      |   GROUP BY s.simple_sku;                      |                                               |
|      |                                               |                                               |
| 5    | qty === 10                                    |                                               |
|      |                                               |                                               |
| 6    | INSERT INTO reservation ....                  | [WAIT]                                        |
|      |                                               |                                               |
| 7    | SELECT s.qty - COUNT(r.fk_stock) AS qty       |                                               |
|      |   FROM stock s                                |                                               |
|      |   LEFT JOIN reservation r                     | [WAIT]                                        |
|      |   WHERE s.sku = SKU0                          |                                               |
|      |   GROUP BY s.simple_sku;                      |                                               |
|      |                                               |                                               |
| 8    | qty === 9                                     |                                               |
|      |                                               |                                               |
| 9    | UPDATE stock SET qty = 9                      |                                               |
|      |                                               |                                               |
| 10   | COMMIT;                                       |                                               |
|      |                                               |                                               |
| 11   |                                               | [GOT THE LOCK]                                |
|      |                                               |                                               |
| 12   |                                               | SELECT s.qty - COUNT(r.fk_stock) AS qty       |
|      |                                               |   FROM stock s                                |
|      |                                               |   LEFT JOIN reservation r                     |
|      |                                               |   WHERE s.sku = SKU0                          |
|      |                                               |   GROUP BY s.simple_sku;                      |
|      |                                               |                                               |
| 13   |                                               | qty === 10 <=== it should be 9                |
|      |                                               |                                               |
| 14   |                                               | INSERT INTO reservation ....                  |
|      |                                               |                                               |
| 15   |                                               | SELECT s.qty - COUNT(r.fk_stock) AS qty       |
|      |                                               |   FROM stock s                                |
|      |                                               |   LEFT JOIN reservation r                     |
|      |                                               |   WHERE s.sku = SKU0                          |
|      |                                               |   GROUP BY s.simple_sku;                      |
|      |                                               |                                               |
| 16   |                                               | qty === 9 <=== it should be 8                 |
|      |                                               |                                               |
| 17   |                                               | UPDATE stock SET qty = 9                      |
|      |                                               |                                               |
|      |                                               | COMMIT;                                       |
|      |                                               |                                               |
|      |                                               |                                               |
+------+-----------------------------------------------+-----------------------------------------------+

As soon as I set isolation level to READ COMMITTED the problem is gone.

On my local mysql (MySQL 5.6.19) installation, I can do the same operation and I see the right value for qty using REPEATABLE READ isolation level. Not true when using the same dataset that I have on RDS. See the answer below

For what I found the REPEATABLE READ isolation level creates a read view at the beginning of first read and keeps reading values from that “view”. The READ COMMITTED instead will create a read view for every read in a transaction, reading always the most fresher values.

This may explain …, but I would expect to have the same behaviour also on my local mysql.

This explain what’a happening on RDS.

Has someone experienced something like this before?


Viewing all articles
Browse latest Browse all 35

Trending Articles