Правильная поза для интерпретации индексов и транзакций mysql

MySQL

1. Что делает индекс?

Много раз, когда ваше приложение медленно выполняет SQL-запросы, вам следует подумать о том, можно ли построить индекс.

Большинство индексов MySQL (PRIMARY KEY, UNIQUE, INDEX и FULLTEXT) находятся вB-деревов хранилище. R-деревья используются только для пространственных индексов типа столбца, а таблицы MEMORY также поддерживают хэш-индексы.

Индекс представляет собой отсортированный список, в котором хранится значение индекса и физический адрес строки, содержащей данные, содержащие значение.Когда данных очень много, индекс может значительно ускорить запрос, так как после использования index вы можете вместо сканирования всей таблицы, чтобы найти данные строки, сначала найти физический адрес, соответствующий строке данных, через индексную таблицу, а затем получить доступ к соответствующим данным.

Преимущества и недостатки индексации

Преимущество: он может быстро получить, уменьшить количество операций ввода-вывода и ускорить поиск, группировка и сортировка по индексу может ускорить группировку и сортировку;

недостаток: сам индекс также является таблицей, поэтому он будет занимать место для хранения.Вообще говоря, пространство, занимаемое таблицей индексов, в 1,5 раза больше, чем таблица данных; обслуживание и создание таблицы индексов требует временных затрат, и эти затраты увеличивается с увеличением объема данных; Построение индекса снизит эффективность операций модификации таблицы данных (удаление, добавление, изменение), потому что индексную таблицу необходимо модифицировать во время изменения таблицы данных;

В-третьих, классификация индекса

Общие типы индексов:Индекс первичного ключа, уникальный индекс, общий индекс, полнотекстовый индекс, составной индекс

1,индекс первичного ключа: первичный индекс, основанный на первичном ключе pk_clolum (длина), не допускает дублирования и не допускает нулевых значений;

ALTER TABLE 'table_name' ADD PRIMARY KEY('id');

2,уникальный индекс: значение столбца, используемого для построения индекса, должно быть уникальным, допускаются нулевые значения.

ALTER TABLE 'table_name' ADD UNIQUE('email');

3.нормальный индекс: Индекс построен с обычными столбцами в таблице без каких-либо ограничений.

ALTER TABLE 'table_name' ADD INDEX index_name('description');

4.полный текстовый указатель: Индекс, построенный с столбцами больших текстовых объектов (объясняется в следующем разделе)

ALTER TABLE 'table_name' ADD FULLTEXT('content');

5.составной индекс: индекс, созданный с комбинацией нескольких столбцов, значения в этих нескольких столбцах не могут иметь нулевые значения.

ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3');

Следуя принципу «крайнего левого префикса», наиболее часто используемые столбцы для поиска или сортировки помещаются в крайнее левое положение, а столбцы по очереди уменьшаются. Комбинированный индекс эквивалентен установлению трех индексов col1, col1col2 и col1col2col3, а не index можно использовать для col2 или col3.

При использовании составного индекса ключ индекса может быть слишком большим, поскольку длина имени столбца слишком велика, что снижает эффективность.Если разрешено, вы можете взять в качестве индекса только первые несколько символов col1 и col2

ALTER TABLE 'table_name' ADD INDEX index_name(col1(4),col2(3));

Указывает, что первые 4 символа столбца 1 и первые 3 символа столбца 2 используются в качестве индексов.

В-четвертых, реализовать принцип индексации

MySQL поддерживает множество механизмов хранения, а различные механизмы хранения поддерживают индексы по-разному, поэтому база данных MySQL поддерживает несколько типов индексов, таких как индекс BTree, индекс B+Tree, хэш-индекс, полнотекстовый индекс и т. д.

1. Хэш-индекс:

Только механизм хранения в памяти (памяти) поддерживает хэш-индекс.Хеш-индекс использует значение столбца индекса для вычисления хэш-кода значения, а затем сохраняет физическое расположение данных строки значения в соответствующей позиции хэш-кода. , Поскольку используется хеш-алгоритм, скорость доступа очень высокая, но значение может соответствовать только одному хеш-коду, и это метод распределения хэша, поэтому хэш-индекс не поддерживает функцию поиска и сортировки диапазона. .

2. Полнотекстовый индекс:

FULLTEXT (полнотекстовый) индекс, который можно использовать только в MyISAM и InnoDB, для больших данных создание полнотекстового индекса занимает очень много времени и места. Для больших текстовых объектов или больших данных типа CHAR, если вы используете обычные индексы, по-прежнему возможно сопоставить первые несколько символов текста, но если вы хотите сопоставить несколько слов в середине текста, вы должны использовать LIKE %word% Для сопоставления требуется много времени на обработку, и время ответа будет сильно увеличено.В этом случае можно использовать FULLTEXT индекс.При генерации FULLTEXT индекса будет сгенерирован список слов для текст.Указатель по списку этого слова. FULLTEXT можно создать при создании таблицы или добавить при необходимости с помощью ALTER или CREATE INDEX:

//创建表的时候添加FULLTEXT索引
CTREATE TABLE my_table(
id INT(10) PRIMARY KEY,
name VARCHAR(10) NOT NULL,
my_text text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
FULLTEXT(my_text));

//创建表以后,在需要的时候添加FULLTEXT索引
ALTER my_table ADD FULLTEXT ft_index(my_text);
CREATE INDEX ft_index ON my_table(my_text);

Для больших наборов данных добавление данных в таблицу без FULLTEXT-индекса, а затем добавление FULLTEXT-индекса выполняется быстрее, чем добавление данных в таблицу, которая уже имеет FULLTEXT-индекс.

Полнотекстный индекс с MySQL может использовать только механизм хранения Myiasam. Если это другой механизм данных, полный текстовый индекс не вступит в силу.

В MySQL отключение полнотекстового индексирования полезно на английском языке и в настоящее время не поддерживает китайский язык.

В MySQL, если полученная строка слишком коротка для получения ожидаемых результатов, полученная строка имеет длину не менее 4 байтов, и если извлеченные символы включают стоп-слова, стоп-слова игнорируются.

3. Индекс BTree и индекс B+Tree

Индекс BTree

BTree — это сбалансированное дерево поиска с несколькими ветками.Если степень дерева равна d (d>1) и высота равна h, то BTree должно удовлетворять следующим условиям:

Высота каждого листового узла одинакова, равна h;

Каждый нелистовой узел состоит из n-1 ключей и n точек-указателей, где d

Все указатели конечных узлов равны нулю;

Ключами нелистовых узлов являются все кортежи [key, data], где key представляет собой ключ, используемый в качестве индекса, а data — это данные строки, в которой находится значение ключа;

Структура BTree выглядит следующим образом:

image

В организации BTREE можно использовать метод поиска двоичных поисков. Поисковая сложность является H * log (n). Вообще говоря, высота дерева очень маленькая, обычно около 3, поэтому BTREE является очень эффективным поиском , Структура.

B+древовидный индекс

B+Tree является вариантом BTree. Пусть d будет степенью дерева, а h будет высотой дерева. Основное различие между B+Tree и BTree заключается в следующем:

Неконечные узлы в B+Tree не хранят данные, только ключевые значения;

Листовой узел B+Tree не имеет указателя, все значения ключа будут отображаться на листовом узле, а физический адрес данных соответствует значению ключа, хранящемуся в ключе;

Структура B+Tree выглядит следующим образом:

image

Вообще говоря, B+Tree больше подходит для реализации индексной структуры внешней памяти, чем BTree, потому что специалисты по проектированию механизма хранения умело используют структуру хранения внешней памяти (диска), то есть сектор диска представляет собой целое число, кратное странице (странице), страница — это единица хранения, обычно 4 КБ по умолчанию, поэтому узел структуры индекса рассчитан на размер страницы, а затем с использованием принципа «предварительного чтения» внешнего памяти, каждый раз при чтении данные всего узла считываются в память, а затем ищутся в памяти.Известно, что скорость чтения памяти в сотни раз выше, чем скорость чтения ввода-вывода внешней памяти, поэтому ключом к повышению скорости поиска является использование как можно меньше дискового ввода-вывода. , то вы можете знать, что чем больше количество ключей в каждом узле, чем меньше высота дерева, тем меньше количество операций ввода-вывода. O требуется, поэтому в целом B+Tree быстрее, чем BTree, потому что B+Tree не является. Если данные не хранятся в листовых узлах, можно хранить больше ключей.

B+TREE с последовательным индексом

Многие подсистемы хранения оптимизированы на основе B+Tree, добавляя указатели на соседние конечные узлы для формирования B+Tree с последовательными указателями доступа, чтобы повысить эффективность поиска по интервалам, если найден первый. вы можете искать следующие значения последовательно.

Структура B+Tree выглядит следующим образом:

image

Проанализировав принцип реализации структуры индекса MySQL, давайте посмотрим, как конкретный механизм хранения реализует структуру индекса.Двумя наиболее распространенными механизмами хранения в MySQL являются MyISAM и InnoDB, которые реализуют некластеризованный индекс и кластеризацию соответственно.

Во-первых, вы должны ввести несколько понятий: при классификации индекса мы можем разделить «Основной индекс» и «Вспомогательный индекс» в соответствии с ключом индекса, а индекс, созданный с использованием значения первичного ключа, называется «основной индекс», другие «Называется «вспомогательный указатель». Следовательно, у основного индекса может быть только один, а у вспомогательного может быть много.

MyISAM — некластеризованный индекс

Механизм хранения MyISAM использует некластеризованный индекс. Первичный и вторичный индексы некластеризованного индекса почти одинаковы, за исключением того, что первичный индекс не допускает дублирования или нулевых значений. Ключи их конечных узлов хранятся, указывая на соответствующие значения ключей Физический адрес данных.

Таблица данных и индексная таблица некластеризованного индекса хранятся отдельно.

Данные в некластеризованном индексе хранятся в соответствии с порядком вставки данных. Поэтому некластеризованные индексы больше подходят для одиночного запроса данных. На порядок размещения не влияют ключевые значения.

Полнотекстовые индексы доступны только в MyISAM.

Сначала я не понял, почему первичный индекс и вторичный индекс некластеризованного индекса указывают на одно и то же содержимое, зачем использовать вторичный индекс? Позже я понял, что индекс не используется для запросов, это он используется в тех местах, нет ли он после операторов WHERE и ORDER BY, то что, если условие запроса не является первичным ключом, тогда необходим вторичный индекс.

InnoDB-- кластерный индекс

Листовой узел первичного индекса кластеризованного индекса хранит данные, соответствующие самому значению ключа, а конечный узел вспомогательного индекса хранит значение ключа первичного ключа данных, соответствующих значению ключа. Следовательно, чем меньше длина значения первичного ключа, тем лучше, а чем проще тип, тем лучше.

Данные кластеризованного индекса хранятся вместе с индексом первичного ключа.

Данные кластеризованного индекса хранятся в соответствии с порядком первичного ключа. Следовательно, он подходит для интервального поиска, индексируемого по первичному ключу, который может иметь меньше дисковых операций ввода-вывода и ускорить запрос. Но также и по этой причине порядок вставки кластеризованного индекса лучше всего вставлять в порядке монотонного первичного ключа, иначе это будет вызывать частые разбиения страниц и серьезно сказываться на производительности.

В InnoDB, если вам нужно найти только индексированный столбец, старайтесь не добавлять другие столбцы, что повысит эффективность запроса.

При использовании первичного индекса более удобно использовать кластеризованный индекс, потому что кластеризованный индекс нужно искать только один раз, а некластеризованный индекс должен выполнять поиск ввода-вывода для данных после нахождения адреса данные.

Поскольку кластеризованный вторичный индекс хранит значение ключа первичного ключа, он может снизить комиссионные расходы при перемещении строк данных или разделении страниц, поскольку в настоящее время нет необходимости поддерживать вторичный индекс. Но вторичные индексы занимают больше места.

Кластерированный индекс при вставке новых данных намного медленнее, чем не кластеризованный индекс, из-за необходимости повторяют, следует ли повторять первичный ключ при вставке новых данных, которые необходимы для прохождения всех узлов листа основного индекса, а не сохранить кластерный индекс Узлы являются адресатыми данными, занимать меньше места, и, следовательно, распределение концентрации, когда запрос в I / O меньше, но основной кластерный индекс индекса хранится в самом данных, большим пространством данных, большую распределение, сектор может Занимайте много и, следовательно, требуют больше времени ввода / вывода для прохождения.

Следующий рисунок может быть представлен изображением кластеризованного индекса и некластеризованного индекса.

image

Пять, стратегия использования индекса

Когда следует использовать индекс?

Первичный ключ автоматически создает уникальный индекс;

Столбцы, которые часто используются в качестве условий запроса в откуда или порядке по операциям, должны быть проиндексированы;

Индексироваться как отсортированный столбец;

Поля, связанные с другими таблицами в запросе, взаимосвязи внешнего ключа индексируются

Склонность к объединению индексов в условиях высокой параллелизма;

Когда не использовать индекс?

Не создавайте индексы для часто добавляемых, удаляемых и изменяемых столбцов;

Имеется большое количество повторяющихся столбцов, которые не индексируются;

Если записей в таблице слишком мало, не создавайте индекс;

В составном индексе не может быть столбца со значением NULL. Если он есть, то этот столбец недействителен для составного индекса;

В операторе SELECT индекс можно использовать только один раз.Если он используется в WHERE, его нельзя использовать в ORDER BY;

В операции LIKE '%aaa%' не будет использовать индекс, то есть индекс будет недействительным, но 'aaa%' может использовать индекс;

Использование выражения или функции в индексированном столбце приведет к аннулированию индекса, например: выберите * из пользователей, где YEAR(adddate)

При использовании регулярных выражений в условиях запроса индексы можно использовать только в том случае, если первый символ шаблона поиска не является подстановочным знаком.

Использование в состоянии запроса приведет к аннулированию индекса.

Использование NULL в условиях запроса может вызвать сбой индекса.

Использование ИЛИ для соединения нескольких условий в условии запроса приведет к сбою индекса. В этом случае его следует изменить на два запроса, а затем соединить с помощью UNION ALL.

Старайтесь не включать сортировку по нескольким столбцам.Если необходимо, лучше построить составной индекс для этой очереди;

Только когда в базе данных достаточно тестовых данных, результаты ее тестов производительности имеют практическую справочную ценность. Если в тестовой базе данных всего несколько сотен записей данных, часто все они загружаются в память после выполнения первой команды запроса, что заставит последующие команды запроса выполняться очень быстро — с индексами или без них. Только когда в базе данных более 1000 записей и общий объем данных превышает общий объем памяти на сервере MySQL, результаты теста производительности базы данных имеют смысл.

Шесть, оптимизация индекса

1, самый левый префикс

Самый левый префикс индекса связан с "принципом самого левого префикса" в B+Tree. Например, если установлен комбинированный индекс , индекс может использоваться в следующих 3 случаях: col1, , , другие столбцы, такие как , , col2, col3 и т. д., не могут использовать индексы.

В соответствии с принципом самого левого префикса мы обычно помещаем столбец с наибольшей частотой сортировки в крайний левый и так далее.

2. Оптимизация нечетких запросов с индексом

Как упоминалось выше, при использовании LIKE для нечеткого запроса «%aaa%» не будет использовать индекс, то есть индекс будет недействительным. В этом случае вы можете использовать только полнотекстовое индексирование для оптимизации (упомянутое выше).

Создайте полнотекстовый индекс для критериев поиска, а затем использовать

SELECT * FROM tablename MATCH(index_colum) ANGAINST(‘word’);

Введение в бизнес

Во-первых, что такое транзакция? Транзакция представляет собой пакет sql-операторов, но этот пакет представляет собой атом (атом), неделимый, либо все выполненный, либо не выполненный откат (откат).

Транзакции MySQL в основном используются для обработки данных с большим количеством операций и высокой сложностью. Например, в системе управления персоналом, если вы удаляете человека, вам необходимо удалить как основную информацию о человеке, так и информацию, связанную с человеком, такую ​​как почтовые ящики, статьи и т. д. Таким образом, эти инструкции по работе с базой данных составляют сделку!

  • Транзакции поддерживаются в MySQL только для баз данных или таблиц, которые используют ядро ​​базы данных Innodb.

  • Обработку транзакций можно использовать для поддержания целостности базы данных, гарантируя, что либо все пакеты операторов SQL будут выполнены, либо ни один из них не будет выполнен.

  • Транзакции используются для управления операторами вставки, обновления и удаления.

В целом транзакция должна соответствовать 4 условиям (ACID): Атомарность, Непротиворечивость, Изоляция, DURABILITY (надежность)

  • 1, атомарность транзакций: набор транзакций или успешен, или отозван.

  • 2. Стабильность: если есть недопустимые данные (ограничения внешнего ключа и т. д.), транзакция отзывается.

  • 3. Изоляция. Транзакции выполняются независимо. Если результат транзакции влияет на другие транзакции, то другие транзакции будут отозваны. 100% изоляция транзакций за счет скорости.

  • 4. Надежность: после сбоя программного и аппаратного обеспечения драйвер таблицы данных InnoDB будет использовать файл журнала для его восстановления и изменения. Надежность и высокая скорость не могут сочетаться друг с другом, опция innodb_flush_log_at_trx_commit определяет, когда транзакции сохраняются в журнал.

image

Параллелизм транзакций не выполняет грязные чтения, фантомные чтения и неповторяющиеся чтения, вызванные изоляцией транзакций.

  • Грязное чтение: транзакция A считывает данные, измененные незафиксированной транзакцией B. Если транзакция B терпит неудачу и откатывается на полпути, транзакция A читает грязные данные. Например, когда транзакция A изменяет деньги, транзакция B считывает результат обновления транзакции A, но если транзакция A откатывается позже, транзакция B считывает грязные данные.

  • Неповторяющееся чтение: в одной и той же транзакции результаты чтения одних и тех же данных противоречивы. Транзакция A читает до того, как транзакция B обновляет данные, затем транзакция B обновляет и фиксирует, а транзакция A читает снова.В это время данные, прочитанные дважды, различаются.

  • Фантомное чтение: (В одной и той же транзакции результаты, возвращаемые одним и тем же запросом несколько раз, различаются. Транзакция B запрашивает количество записей в таблице, затем транзакция A вставляет запись в таблицу, а затем транзакция B снова запрашивает и находит что количество записей разное.Обратите внимание на это объяснение.Не правильное,таких объяснений в интернете много,в том числе эксперты,которые я считаю более авторитетными,но после экспериментов оказывается неверным.Так что это требует внимания ). Вы можете провести такой эксперимент: транзакция A запрашивает количество записей, транзакция B вставляет запись (значение первичного ключа равно 6), отправляет, а затем транзакция A запрашивает количество записей и обнаруживает, что количество записей не изменилось. изменился, но в это время вставляет значение первичного ключа 6. Записи обнаружили конфликт, и это было похоже на галлюцинацию.

разница

1. Грязное чтение и неповторяемое чтение. Грязное чтение — это транзакция, которая считывает обновленные данные транзакции, которая еще не была зафиксирована. Неповторяющееся чтение — это одна и та же транзакция, данные, прочитанные несколько раз, различаются.

2. Отличие неповторяемого чтения от фантомного чтения: оба в одной транзакции, первое отличается чтением данных несколько раз, а второе отличается чтением данных целиком.

уровень изоляции

image

image

  • Изменения уровня изоляции влияют на циклы блокировки

  • MySQL поддерживает указанные выше четыре уровня изоляции, по умолчанию используется повторяемое чтение.

image

image

MySQL имеет три уровня блокировки: уровень страницы, уровень таблицы и уровень строки.

  Механизмы хранения MyISAM и MEMORY используют блокировку на уровне таблицы;

  Подсистема хранения BDB использует блокировку на уровне страницы, но также поддерживает блокировку на уровне таблицы;

  Подсистема хранения InnoDB поддерживает блокировку как на уровне строк, так и на уровне таблиц, но по умолчанию

Он использует блокировку на уровне строки.

Характеристики этих трех типов блокировок MySQL можно приблизительно обобщить следующим образом: 1. Блокировки на уровне таблицы: низкие накладные расходы и быстрая блокировка, отсутствие взаимоблокировок, высокая степень детализации блокировок, самая высокая вероятность конфликтов блокировок и самый низкий уровень параллелизма. Блокировки на уровне таблицы позволяют нескольким потокам читать данные из таблицы данных одновременно, но если другой поток хочет записать данные, он должен сначала получить эксклюзивный доступ (монопольные блокировки таблицы добавляются по умолчанию); (Блокировка чтения таблицы) Когда обновляя данные, он должен дождаться завершения обновления, прежде чем другие потоки смогут получить доступ (прочитать) к таблице (Эксклюзивная блокировка записи (Table Write Lock))

2. Блокировки на уровне строк: большие накладные расходы, медленная блокировка, тупиковые ситуации, наименьшая степень детализации блокировки, наименьшая вероятность конфликтов блокировок и наивысший уровень параллелизма.

3. Блокировки страниц: накладные расходы и время блокировки находятся между блокировками таблиц и блокировками строк, будут возникать взаимоблокировки, степень детализации блокировок находится между блокировками таблиц и блокировками строк, а степень параллелизма является общей.

В принципе, когда таблица данных имеет блокировку чтения, другие процессы не могут обновлять таблицу, но при определенных условиях таблицы MyISAM также поддерживают параллельные операции запроса и вставки.

В общем, таблица движка MyISAM также поддерживает параллельное выполнение операций запроса и вставки (в принципе, когда таблица данных имеет блокировку чтения, другие процессы не могут обновлять таблицу)

Механизм MyISAM имеет системную переменную concurrent_insert, которая специально используется для управления поведением параллельной вставки.Ее значение может быть 0, 1 или 2 соответственно:

a、concurrent_insert为0,不允许并发插入。     
b、concurrent_insert为1,如果MyISAM表中没有空洞(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录。这也是MySQL的默认设置。     
c、concurrent_insert为2,无论MyISAM表中有没有空洞,都允许在表尾并发插入记录。

Если одновременно есть запросы на чтение и запись, MYSQL отдаст приоритет операции записи. Таким образом, когда таблица MyISAM выполняет большое количество операций обновления (особенно при наличии индекса в обновляемом поле), операции запроса будет сложно получить блокировку чтения, что приведет к блокировке запроса.

Мы также можем настроить приоритет чтения и записи MyISAM:

  a、通过指定启动参数low-priority-updates,使MyISAM引擎默认给予读请求以优先的权利。
  b、通过执行命令SET LOW_PRIORITY_UPDATES=1,使该连接发出的更新请求优先级降低。
  c、通过指定INSERT、UPDATE、DELETE语句的LOW_PRIORITY属性,降低该语句的优先级。

MyISAM использует функцию класса flock, которая напрямую блокирует весь файл (так называемая блокировка файла).Таблица данных MyISAM хранится в одном файле и может быть заблокирована для одного файла таблицы;

InnoDB использует функции класса fcntl, которые могут блокировать локальные данные в файле (так называемая блокировка строк).InnoDB представляет собой целый файл, и все индексы, данные и структуры хранятся в файле ibdata, поэтому необходимо использовать блокировку строк.

Заявление о контроле транзакций:

BEGIN或START TRANSACTION;显式地开启一个事务;     
COMMIT;也可以使用COMMIT WORK,不过二者是等价的。
COMMIT会提交事务,并使已对数据库进行的所有修改称为永久性的;      
ROLLBACK;有可以使用ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;      
SAVEPOINT identifier;SAVEPOINT允许在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT;     
RELEASE SAVEPOINT identifier;删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;     
ROLLBACK TO identifier;把事务回滚到标记点;     
SET TRANSACTION;用来设置事务的隔离级别。
InnoDB存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE。

Существует два основных метода обработки транзакций MYSQL:

1. ИСПОЛЬЗОВАТЬ НАЧАЛО, ОТТЕРТАТЬ, ПОБЕДИТЬСЯ

BEGIN 开始一个事务     
ROLLBACK 事务回滚    
COMMIT 事务确认

2. Используйте SET напрямую, чтобы изменить My

Режим автоматической фиксации SQL:

SET AUTOCOMMIT=0 禁止自动提交     
SET AUTOCOMMIT=1 开启自动提交

будь осторожен

1. Если sql работает корректно в транзакции и за ним нет коммита, результат не будет обновлен в БД, поэтому нужно вручную добавить коммит.

2. Если в транзакции есть ошибка в каком-то операторе sql, оператор ошибки не будет выполняться позже. Мы можем подумать, что правильная операция будет отброшена и отменена, но на самом деле правильная операция не была отменена.В это время, если коммит сделан без ошибки, предыдущая правильная операция вступит в силу, и база данных будет обновлена .