Problems encountered by MySQL nested transactions

Problems encountered by MySQL nested transactions

MySQL supports nested transactions, but not many people do it... Some time ago, I saw some foreigners arguing about the necessity of MySQL nested transactions. It's so funny, is there any scenario where this nested weird usage is necessary? I talked to my former DBA colleague and learned that MySQL nested transactions should not be used in any scenario.

So what problems will you encounter when using MySQL nested transactions?

mysql> select * from ceshi; 
+------+ 
| n | 
+------+ 
| 1 | 
+------+ 
1 row in set (0.00 sec) 
 
mysql> start transaction; 
Query OK, 0 rows affected (0.00 sec) 
 
mysql> insert into ceshi values(2); 
Query OK, 1 row affected (0.00 sec) 
 
mysql> start transaction; 
Query OK, 0 rows affected (0.00 sec) 
 
mysql> insert into ceshi values(3); 
Query OK, 1 row affected (0.00 sec) 
 
mysql> commit; 
Query OK, 0 rows affected (0.00 sec) 
 
mysql> rollback; 
Query OK, 0 rows affected (0.00 sec) 


Although I rolled back at the end, the data showed 1 2 3. Originally, everyone thought that although my transaction was in a nested state, it rolled back at the end. In fact, the result we hope to see is that the sub-transaction is executed successfully, and the failure of the outer transaction will be rolled back. But this is not the case, the final result is 1 2 3 .

+-----+ 
| n | 
+-----+ 
| 1 | 
| 2 | 
| 3 | 
+-----+ 

When the SQL interpreter encounters start transaction, commit will be triggered... !!!

begin_1 sql_1 begin_2 sql_2 sql_3 commit_1 rollback_1 .

When begin_2 is executed, sql_1 has already been committed. When you execute commit_1, sql_2 and sql_3 have already been committed. At this time, if you rollback, it will be useless... because they have already been committed, what can you roll back...

As mentioned before, in architecture, few people use nested transactions, but sometimes they are nested accidentally. Let’s take the Python project as an example. First, we use decorators to implement transaction packaging. Then, the data processing def a() and def b() functions are wrapped in transactions. It doesn’t matter if we simply use a or b, as they are all single transactions. If a calls b in the logic, what will happen? Yes, transactions are nested... I think this is a problem that most business developers will encounter.

So how to avoid this risk? You can lock it... Set up a global lock and check the lock status before creating a subtransaction...

If you are using the flask framework, you can use the flask g global variable.

If it is the Django framework, you can use thread local to use global variables.

If it is an asynchronous io architecture such as tornado or gevent, you can use fd to associate the coroutine variables.

@decorator
def with_transaction(f, *args, **kwargs):
 
  db = connection.get_db_by_table("*")
  try:
    db.begin()
    ret = f(*args, **kwargs)
    db.commit()
  except:
    db.rollback()
    raise
  return ret
 
 
@with_transaction
def hide(self):
  '''Orders are not displayed on the app'''
  if self.status not in OrderStatus.allow_deletion_statuses():
    raise OrderStatusChangeNotAllowed(self.status, OrderStatus.deleted)
...
 
 
@with_transaction
def change_receipt_info(self, address, name, phone):
  region = Region.get_by_address(address)
  ...

When we execute the following statement, the transaction will be forced to commit. Of course, the premise here is autocommit = True.

ALTER FUNCTION  
ALTER PROCEDURE  
ALTER TABLE  
BEGIN  
CREATE DATABASE  
CREATE FUNCTION  
CREATE INDEX  
CREATE PROCEDURE  
CREATE TABLE  
DROP DATABASE  
DROP FUNCTION  
DROP INDEX  
DROP PROCEDURE  
DROP TABLE  
UNLOCK TABLES  
LOAD MASTER DATA  
LOCK TABLES  
RENAME TABLE  
TRUNCATE TABLE  
SET AUTOCOMMIT=1  
START TRANSACTION  

You may also be interested in:
  • Two solutions for implementing MySQL nested transactions in PHP
  • MySQL stored procedure example (including transactions, output parameters, nested calls)

<<:  Let's talk about the v-on parameter problem in Vue

>>:  How to implement hot deployment and hot start in Eclipse/tomcat

Recommend

Vue element implements table adding, deleting and modifying data

This article shares the specific code of vue elem...

Docker connection mongodb implementation process and code examples

After the container is started Log in to admin fi...

WeChat Mini Program implements the likes service

This article shares the specific code for the WeC...

Implementation of Nginx load balancing cluster

(1) Experimental environment youxi1 192.168.5.101...

Implementation of iview permission management

Table of contents iview-admin2.0 built-in permiss...

Talk about the 8 user instincts behind user experience in design

Editor's note: This article is contributed by...

js object-oriented method to achieve drag effect

This article shares the specific code for impleme...

Springboot+Vue-Cropper realizes the effect of avatar cutting and uploading

Use the Vue-Cropper component to upload avatars. ...

How does JS understand data URLs?

Table of contents Overview Getting started with d...

How to install JDK and Mysql on Ubuntu 18.04 Linux system

Platform deployment 1. Install JDK step1. Downloa...

Detailed explanation of JavaScript to monitor route changes

Table of contents history pushState() Method push...

Mysql date formatting and complex date range query

Table of contents Preface Query usage scenario ca...

Example of implementing load balancing with Nginx+SpringBoot

Introduction to Load Balancing Before introducing...