Transaction and Concurrency Control

1 What is a transaction 

What is a transaction?

  • A transaction is the smallest logic unit performs database operations
  • Transactions can also be composed of a SQL composed of multiple SQL
  • SQL transaction consisting of either all succeed or full execution failed
START TRANSACTION / BEGIN

	SELECT ...
	UPDATE ...
	INSERT ...
	DELETE ...

COMMIT / ROLLBACK

After opening the transaction can only perform DML operations (DDL will execute a COMMIT This transaction will end out)


2 properties Affairs

Characteristics of the transaction

feature

Explanation

Atoms of ( A )

All operations in a transaction, either completed or not completed all, does not end in the middle of a link.

Consistency ( C )

And after the end of the transaction before the transaction began, the integrity of the database is not corrupted.

Isolation ( the I )

Transaction isolation requirements for each read and write transactions with other transaction object of the operation target can be separated from each other, i.e., before submitting the transaction is not visible to other transactions.

Persistent ( D )

Once the transaction is committed, the result is permanent, even if the downtime and other accidents, databases, data can be restored.

3 concurrent problems caused by

3.1 dirty read

One transaction reads data from another uncommitted transactions

 3.2 Non-repeatable read

The same data twice before and after a transaction to read inconsistent.

3.3 Magic Reading

It refers to a transaction inconsistent result set query twice the number of records.


4 transaction isolation

INNODB isolation level

  • The default Repeatable read (SQL standard which can not be avoided phantom read, but MySQL can)

Isolation Levels

Dirty read Non-repeatable read Magic Reading Isolation Concurrency

Sequential read (SERIALIZABLE)

N N N highest lowest

Repeatable Read (REPEATABLE READ)

N N N    

Reading for submission (READ COMMITTED)

N Y Y    
Uncommitted Read (READ UNCOMMITTED) Y Y Y lowest highest

 Set the transaction isolation level

SET [PERSIST|GLOBAL|SESSION]
     TRANSACTION ISOLATION LEVEL
     {
      READ UNCOMMITTED
      | READ COMMITTED
      | REPEATABLE READ
      | SERIALIZABLE
     }

Case serializable level two concurrent transactions

# 事务1
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE ;
SHOW VARIABLES LIKE '%iso%';

BEGIN;
SELECT * FROM `employees` WHERE `emp_no` < '10003' ;
# ROLLBACK;
# COMMIT;
# 事务2
# 修改前一个事务里面查询出来的数据
BEGIN;
UPDATE `employees` SET `hire_date` = '1997-06-06' WHERE `emp_no` = '10002';
ROLLBACK;

 1 transactions executed rollback; after the transaction to proceed 2

repeatable read 级别两个事务并发的情况

# 事务1
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;
SHOW VARIABLES LIKE '%iso%';

BEGIN;
SELECT * FROM `employees` WHERE `emp_no` < '10003' ;
# ROLLBACK ;
# 无法读取到第二个事务对数据的修改
# 如果还在这个事务内,这个时候是读取不到事务2修改的值的
SELECT * FROM `employees` WHERE `emp_no` < '10003' ;
# 事务2
# 修改前一个事务里面查询出来的数据
BEGIN;
UPDATE `employees` SET `hire_date` = '1997-06-06' WHERE `emp_no` = '10002';
COMMIT ;

read committed 级别两个事务并发的情况

# 事务1
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SHOW VARIABLES LIKE '%iso%';
# 能够查询出来,另一个事务的修改
BEGIN;
SELECT * FROM `employees` WHERE `emp_no` < '10003' ;
COMMIT;
# 事务2
# 修改前一个事务里面查询出来的数据
BEGIN;
UPDATE `employees` SET `hire_date` = '2007-06-06' WHERE `emp_no` = '10002';
COMMIT;

read uncommitted 级别两个事务并发的情况

# 事务1
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SHOW VARIABLES LIKE '%iso%';
# 能够查询出来,事务1还未提交的数据
BEGIN;
SELECT * FROM `employees` WHERE `emp_no` < '10003' ;
COMMIT;
# 事务2
# 修改前一个事务里面查询出来的数据
BEGIN;
UPDATE `employees` SET `hire_date` = '1996-06-06' WHERE `emp_no` = '10002';
# ROLLBACK第一个事务的查询结果也会跟着变化
ROLLBACK;

repeatable read 级别下的阻塞

# 事务1
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SHOW VARIABLES LIKE '%iso%';

BEGIN;
UPDATE salaries SET salary = salary + 1 WHERE to_date BETWEEN '2001-01-01' AND '2001-01-31' ;
COMMIT;
# 事务2
BEGIN;
UPDATE salaries SET salary = salary - 1 WHERE to_date BETWEEN '2001-01-01' AND '2001-01-31' ;

INNODB中的锁(一个事务不能对另一个事务正在读取或修改的数据进行修改)

  • 查询需要对资源加共享锁(S)(被加锁的对象只能被持有锁的事务读取但不能修改,其他事务无法对该对象进行修改,但也可以对该对象加共享锁进行读取)
  • 数据修改需要对资源加排它锁(ⅹ)(被加了排他锁的对象只能被持有锁的事务读取和修改,其他事务无法读取修改被加了排他锁的对象)
 

排它锁

共享锁

排它锁

不兼容

不兼容

共享锁 不兼容 兼容

5 阻塞和死锁

5.1 阻塞

什么是阻塞?

  • 由于不同锁之间的兼容关系,造成的一事务需要等待另一个事务释放其所占用的资源的现象

 如何发现阻塞?

# 事务1
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SHOW VARIABLES LIKE '%iso%';
# 当前连接的连接id 53
SELECT CONNECTION_ID();

BEGIN;
UPDATE salaries SET salary = salary + 1 WHERE salary >= 150000;
# ROLLBACK;
# 事务2
# 当前连接的连接id 51
SELECT CONNECTION_ID();

BEGIN;
UPDATE salaries SET salary = salary - 1 WHERE salary >= 150000;
# ROLLBACK;

 

SELECT
  waiting_pid AS 'blocked pid',
  waiting_query AS 'blocked SQL',
  blocking_pid AS 'running pid',
  blocking_query AS 'running SQL',
  wait_age AS 'blocked time',
  sql_kill_blocking_query AS 'info'
FROM
  sys.`innodb_lock_waits`
WHERE (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(wait_started)) > 30 ;

# kill 53;

 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction 

# 查询当前会话等待事务锁超时时间
SHOW VARIABLES LIKE 'innodb_lock_wait_timeout' ;
# 修改当前会话等待事务锁超时时间:
SET innodb_lock_wait_timeout = 10000 ;

如何处理阻塞?

  • 终止占用资源的事务
  • 优化占用资源事务的SQL,使其尽快释放资源

5.2 死锁

什么是死锁?

  • 并行执行的多个事务相互之间占有了对方所需要的资源

如何发现死锁?

  • set global innodb_print_all_deadlocks = on ;

# 窗口1
# mysql -u root -p123456 employees
# set global innodb_print_all_deadlocks = on ;
# 退出在登陆,使设置生效
BEGIN;
# 第一个执行
UPDATE `employees` SET `gender` = 'F' WHERE `emp_no` = 10001;
# 第三个执行
UPDATE `employees` SET `gender` = 'F' WHERE `emp_no` = 10002;
# 窗口2
BEGIN;
# 第二个执行
UPDATE `employees` SET `gender` = 'F' WHERE `emp_no` = 10002;
# 第四个执行
UPDATE `employees` SET `gender` = 'F' WHERE `emp_no` = 10001;

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

# log_error就是错误日志的位置
SHOW VARIABLES LIKE '%error%';
TRANSACTION 89900, ACTIVE 30 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 63, OS thread handle 26344, query id 7332 localhost ::1 root updating
UPDATE `employees` SET `gender` = 'F' WHERE `emp_no` = 10002
RECORD LOCKS space id 408 page no 5 n bits 408 index PRIMARY of table `employees`.`employees` trx id 89900 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 8; compact format; info bits 0
 0: len 4; hex 80002712; asc   ' ;;
 1: len 6; hex 000000015ef8; asc     ^ ;;
 2: len 7; hex 0200000130087c; asc     0 |;;
 3: len 3; hex 8f58c2; asc  X ;;
 4: len 7; hex 42657a616c656c; asc Bezalel;;
 5: len 6; hex 53696d6d656c; asc Simmel;;
 6: len 1; hex 02; asc  ;;
 7: len 3; hex 8fc856; asc   V;;

TRANSACTION 89901, ACTIVE 15 sec starting index read
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 64, OS thread handle 24768, query id 7333 localhost ::1 root updating
UPDATE `employees` SET `gender` = 'F' WHERE `emp_no` = 10001
RECORD LOCKS space id 408 page no 5 n bits 408 index PRIMARY of table `employees`.`employees` trx id 89901 lock_mode X locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 8; compact format; info bits 0
 0: len 4; hex 80002712; asc   ' ;;
 1: len 6; hex 000000015ef8; asc     ^ ;;
 2: len 7; hex 0200000130087c; asc     0 |;;
 3: len 3; hex 8f58c2; asc  X ;;
 4: len 7; hex 42657a616c656c; asc Bezalel;;
 5: len 6; hex 53696d6d656c; asc Simmel;;
 6: len 1; hex 02; asc  ;;
 7: len 3; hex 8fc856; asc   V;;

RECORD LOCKS space id 408 page no 5 n bits 408 index PRIMARY of table `employees`.`employees` trx id 89901 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 8; compact format; info bits 0
 0: len 4; hex 80002711; asc   ' ;;
 1: len 6; hex 000000015f2c; asc     _,;;
 2: len 7; hex 010000009d284a; asc      (J;;
 3: len 3; hex 8f4322; asc  C";;
 4: len 6; hex 47656f726769; asc Georgi;;
 5: len 7; hex 466163656c6c6f; asc Facello;;
 6: len 1; hex 02; asc  ;;
 7: len 3; hex 8fa022; asc   ";;

如何处理死锁?

  • 数据库自行回滚占用资源少的事务
  • 并发事务按相同顺序占有资源 (1->2->3->4 改为1->4->2->3)

 

发布了515 篇原创文章 · 获赞 97 · 访问量 108万+

Guess you like

Origin blog.csdn.net/qq_40794973/article/details/104057217