MySQL 版本 5.7.27 OS: mac

事务的施加时间

MySQL 事务的开始时间并不是在 begin 或者是 @Transactional 开始的第一行就施加了的.

查询正在进行的事务

  1. SELECT a.trx_id, a.trx_state, a.trx_started, a.trx_query, b.ID, b.USER, b.DB,
  2. b.COMMAND, b.TIME, b.STATE, b.INFO, c.PROCESSLIST_USER, c.PROCESSLIST_HOST, c.PROCESSLIST_DB, d.SQL_TEXT FROM
  3. information_schema.INNODB_TRX a LEFT JOIN information_schema.PROCESSLIST b
  4. ON a.trx_mysql_thread_id = b.id AND b.COMMAND = 'Sleep'
  5. LEFT JOIN PERFORMANCE_SCHEMA.threads c ON b.id = c.PROCESSLIST_ID LEFT JOIN PERFORMANCE_SCHEMA.events_statements_current d ON d.THREAD_ID = c.THREAD_ID;

image.png
而是在第一条需要添加事务的sql执行的时候进行添加. 这一样一来,一些添加 @Transactional 注解的方法的 select 查询是不能用来判断值的. 还需要执行一次添加事务才可以.

RC和RR

和活跃事务生产的 ReadView 是有关系的.

RC: 能够读取到已经事务提交的数据
RR: 不能够读取到事务提交到数据,但是 for update 可以读取到数据 幻读 的产生。

实际可能的代码

  1. @Transactional(rc)
  2. public void hand(){
  3. //1、select * from table where id = xx;
  4. //2、for update 获取x锁
  5. //3、对数据进行更新.
  6. }

这段代码是存在错误的,错误的原因就是对于事务的施加时间理解不到位.

正确的处理是对for update后的数据再次进行查询获取事务锁定的值.