mysql中update的事务

一条update语句在下面的方法开始一个事务

int handler::ha_update_row(const uchar *old_data, uchar *new_data)
{
  int error;
  DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
              m_lock_type == F_WRLCK);
  Log_func *log_func= Update_rows_log_event::binlog_row_logging_function;

  /*
    Some storage engines require that the new record is in record[0]
    (and the old record is in record[1]).
   */
  DBUG_ASSERT(new_data == table->record[0]);
  DBUG_ASSERT(old_data == table->record[1]);

  DBUG_ENTER("hanlder::ha_update_row");
  DBUG_EXECUTE_IF("inject_error_ha_update_row",
                  DBUG_RETURN(HA_ERR_INTERNAL_ERROR); );

  MYSQL_UPDATE_ROW_START(table_share->db.str, table_share->table_name.str);
  mark_trx_read_write();

  DBUG_EXECUTE_IF("handler_crashed_table_on_usage",
                  my_error(HA_ERR_CRASHED, MYF(ME_ERRORLOG), table_share->table_name.str);
                  set_my_errno(HA_ERR_CRASHED);
                  return(HA_ERR_CRASHED););

  MYSQL_TABLE_IO_WAIT(PSI_TABLE_UPDATE_ROW, active_index, error,
    { error= update_row(old_data, new_data);})

  MYSQL_UPDATE_ROW_DONE(error);
  if (unlikely(error))
    DBUG_RETURN(error);
  if (unlikely((error= binlog_log_row(table, old_data, new_data, log_func))))
    DBUG_RETURN(error);
  DBUG_RETURN(0);
  }

但是事务的结束是在int
mysql_execute_command(THD *thd, bool first_level)方法中的最后
  /* report error issued during command execution */
    if (thd->killed_errno())
      thd->send_kill_message();
    if (thd->is_error() || (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR))
      trans_rollback_stmt(thd);
    else
    {
      /* If commit fails, we should be able to reset the OK status. */
      thd->get_stmt_da()->set_overwrite_status(true);
      trans_commit_stmt(thd);
      thd->get_stmt_da()->set_overwrite_status(false);
    }
    if (thd->killed == THD::KILL_QUERY ||
        thd->killed == THD::KILL_TIMEOUT ||
        thd->killed == THD::KILL_BAD_DATA)
是在事务提交之前进行的binlog写入。

提交事务的代码

  thd->get_transaction()->merge_unsafe_rollback_flags();

  if (thd->get_transaction()->is_active(Transaction_ctx::STMT))
  {
    res= ha_commit_trans(thd, FALSE);
    if (! thd->in_active_multi_stmt_transaction())
      trans_reset_one_shot_chistics(thd);
  }
  else if (tc_log)
    res= tc_log->commit(thd, false);
  if (res == FALSE && !thd->in_active_multi_stmt_transaction())
    if (thd->rpl_thd_ctx.session_gtids_ctx().
        notify_after_transaction_commit(thd))
      sql_print_warning("Failed to collect GTID to send in the response packet!");
  /* In autocommit=1 mode the transaction should be marked as complete in P_S */
  DBUG_ASSERT(thd->in_active_multi_stmt_transaction() ||
              thd->m_transaction_psi == NULL);

  thd->get_transaction()->reset(Transaction_ctx::STMT);

你可能感兴趣的:(MYSQL)