8事务

begin/start transaction命令并不是一个事务的起点,执行第一个操作InnoDB表的语句,事务才真正启动。
start transaction with consistent snapshot 命令立即启动事务,但没有创建readview
readview是执行sql语句时创建的。

写数据才会更新隐藏列DB_TRX_ID(最近操作此列的事务),数据库写是一致性的。

事务A 事务B 事务C
start transaction withconsistent snapshot;
start transaction with consistentsnapshot;
update t set k=k+1 where id=1:
update t set k=k+1 where id=1:select k from t where id=1:
select k from t whereid=1;
commit;

事务A:1
事务B:3
事务C:2

示例

sessionA sessionB
begin;select * from t;
update t set c=c+1;
update t set c=0 where id=c;select * from t;

sessionA修改会失败

一致性读和当前读

事务并发控制方式:MVCC和锁

在事务中读取数据时,基于事务开始时的快照(Snapshot)来获取数据,而不是读取最新的数据。
它确保了事务执行期间读取的数据是一致的,不受其他事务修改的影响。

一致性读(Consistent Read) 当前读(Current Read)
定义 在事务中读取数据时,基于事务开始时的快照(Snapshot)来获取数据,而不是读取最新的数据。确保了事务执行期间读取的数据是一致的,不受其他事务修改的影响 事务中读取数据时,直接读取最新的数据,而不是基于快照,用于需要获取最新数据的场景,例如 UPDATE、DELETE 或加锁的 SELECT
实现方式 在 可重复读(REPEATABLE READ) 和 读已提交(READ COMMITTED) 隔离级别下,MySQL 使用 多版本并发控制(MVCC) 实现一致性读。事务开始时,MySQL 会创建一个快照,后续的 SELECT 查询都基于该快照读取数据。 当前读会加锁(如共享锁或排他锁),以确保读取的数据是最新的,常见的当前读操作包括:SELECT … FOR UPDATE、SELECT … LOCK IN SHARE MODE、UPDATE、DELETE
特点 无锁:一致性读不会加锁,因此不会阻塞其他事务的写操作。快照数据:读取的是事务开始时的数据,而不是最新的数据。 加锁:当前读会加锁,可能会阻塞其他事务的写操作。读取的是最新的数据,而不是快照数据。

相关命令

查看事务信息(所有活跃的InnoDB)
select * from information_schema.innodb_trx\G
查找长时间运行的事务
SELECT trx_id, trx_state, trx_started, trx_mysql_thread_id, trx_query
FROM information_schema.innodb_trx
WHERE TIMESTAMPDIFF(SECOND, trx_started, NOW()) > 60; – 查找运行超过60秒的事务
查找处于锁等待状态的事务
SELECT trx_id, trx_state, trx_started, trx_mysql_thread_id, trx_query
FROM information_schema.innodb_trx
WHERE trx_state = ‘LOCK WAIT’;

查找特定线程的事务
SELECT trx_id, trx_state, trx_started, trx_mysql_thread_id, trx_query
FROM information_schema.innodb_trx
WHERE trx_mysql_thread_id = ;

查找持有最多锁的事务
SELECT trx_id, trx_state, trx_started, trx_mysql_thread_id, trx_query, trx_lock_structs
FROM information_schema.innodb_trx
ORDER BY trx_lock_structs DESC
LIMIT 10;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
trx_id	varchar(18)	事务ID(唯一标识符)。
trx_state varchar(13) 事务状态(如 RUNNING, LOCK WAIT, ROLLING BACK, COMMITTING)。
trx_started datetime 事务开始时间。
trx_requested_lock_id varchar(81) 如果事务处于锁等待状态,这里是它请求的锁的ID。
trx_wait_started datetime 如果事务处于锁等待状态,这里是它开始等待的时间。
trx_weight bigint(21) 事务的权重,表示事务的大小或复杂性。
trx_mysql_thread_id bigint(21) 对应的 MySQL 线程 ID。
trx_query varchar(1024) 当前事务正在执行的 SQL 查询(如果有的话)。
trx_operation_state varchar(64) 事务当前的操作状态(例如,正在提交或回滚)。
trx_tables_in_use int(11) 当前事务中正在使用的表的数量。
trx_tables_locked int(11) 当前事务中锁定的表的数量。
trx_lock_structs bigint(21) 当前事务持有的锁的数量。
trx_lock_memory_bytes bigint(21) 当前事务持有的锁所占用的内存字节数。
trx_rows_locked bigint(21) 当前事务锁定的行数。
trx_rows_modified bigint(21) 当前事务修改的行数。
trx_concurrency_tickets bigint(21) 事务在当前会话中的并发票数(用于内部优化)。
trx_isolation_level varchar(16) 事务的隔离级别(如 READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE)。
trx_unique_checks int(1) 是否启用唯一性检查(1 表示启用,0 表示禁用)。
trx_foreign_key_checks int(1) 是否启用外键检查(1 表示启用,0 表示禁用)。
trx_last_foreign_key_error varchar(256) 最近一次的外键错误信息(如果有)。
trx_adaptive_hash_latched int(1) 自适应哈希索引是否被当前事务锁定(1 表示是,0 表示否)。
trx_adaptive_hash_timeout bigint(21) 自适应哈希索引超时值