Analisis terperinci transaksi MySQL

WBOY
Lepaskan: 2022-03-10 17:59:11
ke hadapan
1608 orang telah melayarinya

Artikel ini membawa anda pengetahuan yang berkaitan tentang mysql Ia terutamanya memperkenalkan ciri ACID transaksi MySQL dan sintaks proses kawalan transaksi MySQL, dan memperkenalkan pengecualian yang mungkin berlaku dalam Situasi transaksi serentak. seperti bacaan kotor, bacaan hantu, bacaan tidak boleh diulang, dsb., dan akhirnya memperkenalkan tahap pengasingan transaksi, saya harap ia akan membantu semua orang.

Analisis terperinci transaksi MySQL

Pembelajaran yang disyorkan: tutorial pembelajaran mysql

Dalam senario perniagaan sebenar, cara memastikan integriti operasi adalah isu penting , laksanakan satu siri operasi yang sangat berkaitan secara logik dalam urutan Jika ralat berlaku di tengah-tengah, ia mungkin menyebabkan kekeliruan data.

Bayangkan adegan mengeluarkan wang dari ATM Apabila kita mengeluarkan seribu yuan, ATM akan meludahkan seribu yuan sekaligus selepas pengiraan selesai, bukannya meludahkan seratus yuan setiap kali sepuluh kali. . Ini Untuk memastikan integriti operasi, sama ada seribu yuan ditarik balik sepenuhnya dan bakinya ditolak, atau tidak sesen pun dikeluarkan dan bakinya kekal tidak berubah, tanpa ketidakkonsistenan data yang disebabkan oleh kegagalan mesin di tengah. Operasi lengkap sedemikian dipanggil 事务 transaction Semua operasi dalam transaksi sama ada dilaksanakan dengan jayanya atau tidak dilaksanakan sama sekali.

Artikel ini akan memperkenalkan ciri transaksi ACID MySQL dan sintaks proses kawalan transaksi MySQL, dan memperkenalkan situasi abnormal yang mungkin berlaku dalam pemprosesan transaksi serentak, seperti bacaan kotor, bacaan hantu, bukan- bacaan boleh berulang, dsb. Akhirnya, tahap pengasingan transaksi diperkenalkan.

Mengenai kunci dan MVCC untuk mencapai pengasingan transaksi, kami akan memperkenalkannya dalam artikel kemudian.

Ciri ACID

Pemprosesan transaksi ialah mekanisme pengurusan untuk operasi MySQL yang mesti dilaksanakan dalam satu kelompok semasa proses transaksi, melainkan keseluruhan kumpulan operasi dilaksanakan dengan betul, sebarang operasi dalam tengah Jika ralat berlaku, ia akan 回滚 (Rollback) dikembalikan kepada keadaan selamat awal untuk memastikan tiada perubahan yang salah akan dibuat pada data sistem.

Kami menyebut dalam artikel sebelumnya bahawa selepas MySQL 5.5, enjin storan lalai telah digantikan daripada MyISAM kepada InnoDB Salah satu sebab penting untuk ini adalah kerana InnoDB menyokong transaksi pelbagai enjin storan dalam MySQL. SHOW ENGINES
Analisis terperinci transaksi MySQL Empat ciri urus niaga yang paling penting biasanya dipanggil
ciri ACID
: Transaksi ialah unit minimum yang tidak boleh dibahagikan, dan semua operasi dalam urus niaga itu sama ada berjaya, Atau ia semuanya gagal, tanpa di antaranya. Atomicity dicapai terutamanya melalui A - Atomicity 原子性 dalam log urus niaga Apabila transaksi mengubah suai pangkalan data, InnoDB akan menjana log batal bagi operasi bertentangan sebagai contoh, untuk operasi sisipan, rekod pemadaman akan dihasilkan. Jika transaksi gagal dilaksanakan Atau jika rollback dipanggil, ia akan dipulihkan kepada keadaan sebelum pelaksanaan berdasarkan kandungan log buat asal. 回滚日志(undo log)

: Data berada dalam keadaan konsisten undang-undang sebelum dan selepas pelaksanaan transaksi Walaupun pengecualian berlaku, kekangan integriti pangkalan data, seperti kekangan keunikan, dll. tidak akan dimusnahkan disebabkan oleh. pengecualian. C - Consistency 一致性

: Setiap urus niaga adalah bebas antara satu sama lain dan tidak akan terjejas oleh pelaksanaan urus niaga lain Urus niaga tidak kelihatan kepada transaksi lain sebelum melakukan. Pengasingan ditakrifkan oleh tahap pengasingan transaksi, dan mekanisme kunci digunakan untuk memastikan pengasingan operasi tulis, dan MVCC digunakan untuk memastikan pengasingan operasi baca, yang akan diperkenalkan secara terperinci di bawah. I - Isolation 隔离性

: Pengubahsuaian data selepas transaksi diserahkan adalah berterusan dan tidak akan hilang walaupun pangkalan data tidak berfungsi. Ini dijamin oleh D - Durability 持久性 dalam log transaksi. Sebelum urus niaga diubah suai, maklumat perubahan akan dipratulis ke dalam log buat semula Jika pangkalan data turun, rekod dalam log buat semula akan dibaca selepas pemulihan untuk memulihkan data. 重做日志(redo log)

Sintaks kawalan transaksi

Kawalan transaksi MySQL mempunyai beberapa nod penting, iaitu permulaan transaksi, komit, rollback dan save point.

Membuka urus niaga bermakna urus niaga memulakan pelaksanaan, penyata adalah

atau START TRANSACTION, melakukan transaksi bermakna menulis semua kemas kini dalam urus niaga ke pangkalan data fizikal pada cakera, dan urus niaga berakhir seperti biasa , pernyataannya ialah BEGIN , jika pengecualian berlaku dan rollback diperlukan, pernyataan itu ialah COMMIT. Perlu diingat bahawa apabila transaksi telah dilakukan, ia tidak boleh ditarik balik Oleh itu, apabila pengecualian ditangkap semasa pelaksanaan kod, rollback perlu dilaksanakan secara langsung dan bukannya komit. ROLLBACK

Contohnya, A memindahkan 100 yuan kepada B:

// 正常执行,提交
BEGIN; # 开启事务
UPDATE account_balance SET balance = balance - 100.00 WHERE account_name = 'A';
UPDATE account_balance SET balance = balance + 100.00 WHERE account_name = 'B';
COMMIT; # 提交事务

// 发生异常,回滚
BEGIN; # 开启事务
UPDATE account_balance SET balance = balance - 100.00 WHERE account_name = 'A';
UPDATE account_balance SET balance = balance + 100.00 WHERE account_name = 'B';
ROLLBACK; # 事务回滚
Salin selepas log masuk
Dalam senario yang rumit, kadangkala kita tidak perlu memundurkan keseluruhan operasi, tetapi melaksanakannya secara berkelompok dan melancarkan semula ke tertentu Hanya satu nod sudah memadai, yang bersamaan dengan menyarangkan beberapa sub-urus niaga di bawah transaksi besar Dalam MySQL, anda boleh menggunakan titik pengekalan

untuk mencapai ini. SAVEPOINT

BEGIN;
insert into user_tbl (id) values (1) ;
insert into user_tbl (id) values (2) ;
ROLLBACK;   # 1,2 都没有写入
BEGIN;
insert into user_tbl (id) values (1) ;
SAVEPOINT s1;
insert into user_tbl (id) values (2) ;
ROLLBACK TO s1;   # 回滚到保留点 s1, 因此 1 成功写入,2 被回滚, 最终结果为 1
RELEASE SAVEPOINT s1; # 释放保留点
Salin selepas log masuk

顺便提一下,事务有隐式事务(自动提交)和显示事务(必须手动提交)两种,MySQL 默认为隐式事务,会进行自动提交,通过 autocommit 参数来控制。

# 查看变量
SHOW VARIABLES LIKE 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
# 开启自动提交(默认)
SET autocommit = 1;
# 关闭自动提交
SET autocommit = 0;
Salin selepas log masuk

在自动提交状态下,如果没有显示的开启事务,那每一条语句都是一个事务,系统会自动对每一条 sql 执行 commit 操作。使用 BEGIN 或 START TRANSACTION 开启一个事务之后,自动提交将保持禁用状态,直到使用 COMMIT 或 ROLLBACK 结束事务之后,自动提交模式会恢复到之前的状态。

关于事务还有另一个参数 completion_type,默认取值为 0 (NO_CHAIN)

# 查看变量
SHOW VARIABLES LIKE 'completion_type';
+-----------------+----------+
| Variable_name   |   Value  |
+-----------------+----------+
| completion_type | NO_CHAIN |
+-----------------+----------+
Salin selepas log masuk

completion_type = 0: 默认值,执行 commit 后不会自动开启新的事务。
completion_type = 1: 执行 commit 时,相当于执行 COMMIT AND CHAIN,自动开启一个相同隔离级别的事务。
completion_type = 2: 执行 commit 时,相当于执行 COMMIT AND RELEASE,提交事务后自动断开服务器连接。

事务并发异常

在实际产线环境下,可能会存在大规模并发请求的情况,如果没有妥善的设置事务的隔离级别,就可能导致一些异常情况的出现,最常见的几种异常为脏读(Dirty Read)幻读(Phantom Read)不可重复读(Unrepeatable Read)

脏读

脏读指一个事务访问到了另一个事务未提交的数据,如下过程:

  1. 假设 a 的值为 1,事务 2 把 a 改为 2,此时事务还未提交
  2. 在这个时候,事务 1 读取 a,读得 a 的值为 2,事务 1 读取完成
  3. 结果事务 2 回滚了对 a 的修改(或者是未 commit),于是 a 的值变回 1
  4. 这就导致事实上 a 的值为 1,但是事务 1 取得的结果为 2,所以事务 1 读到了脏数据,发生脏读
    Analisis terperinci transaksi MySQL

不可重复读

不可重复读指一个事务多次读取同一数据的过程中,数据值 内容 发生了改变,导致没有办法读到相同的值,描述的是针对同一条数据 update/delete 的现象,如下过程:

  1. 事务 1 读取 a,此时 a = 1
  2. 此时事务 2 将 a 修改为 2,并成功提交,改动生效
  3. 事务 1 又一次读取 a,此时 a = 2
  4. 事务 1 在同一个事务里面两次读取同一个值,数据值内容却发生了改变,发生不可重复读
    Analisis terperinci transaksi MySQL

幻读

幻读指一个事务多次读取同一数据的过程中,全局数据(如数据行数)发生了改变,仿佛产生了幻觉,描述的是针对全表 insert/delete 的现象,如下过程:

  1. 事务 1 第一次读取数量,得到 10 条数据
  2. 此时事务 2 插入了一条数据并成功提交,改动生效,数据变成 11 条
  3. 事务 1 再次读取数量,得到 11 条数据,对事务 1 而言莫名其妙的多了一条,好像产生幻觉了一样,发生幻读
    Analisis terperinci transaksi MySQL

或者是另一种场景,比如对于有唯一性约束的字段(如 id),发生如下过程:

  1. 事务 1 要插入 id = 5 的记录,先查询数据库,发现不存在 id = 5 的数据,可以正常插入。
  2. 这时候事务 2 插入了一条数据 id = 5。
  3. 事务 1 插入 id = 5 时,发现报错唯一性冲突,对事务 1 来讲就好像见了鬼了,我刚刚明明检查过没有,怎么这时候又有了。
    Analisis terperinci transaksi MySQL

事务隔离级别

串行化的事务处理方式当然是最安全的,但是串行无法满足数据库高并发访问的需求,作为妥协,有时不得不降低数据库的隔离标准来换取事务的并发能力,通过在可控的范围内牺牲正确性来换取效率的提升,这种权衡通过事务的隔离级别来实现。

数据库有 4 种事务隔离级别,由低到高依次为 读未提交 Read Uncommitted读已提交 Read Committed可重复读 Repeatable Read串行化 Serializable

  1. 读未提交 Read Uncommitted
    允许读取未提交的内容,这种级别下的查询不会加锁,因此脏读、不可重复读、幻读都有可能发生。

  2. 读已提交 Read Committed
    只允许读取已提交的内容,这种级别下的查询不会发生脏读,因为脏数据属于未提交的数据,所以不会被读取,但是依然有可能发生不可重复读和幻读。

  3. 可重复读 Repeatable Read (MySQL 的默认隔离级别)
    使用行级锁来保证一个事务在相同查询条件下两次查询得到的数据结果一致,可以避免脏读和不可重复读,但是没有办法避免幻读。

    需要特殊注意的是,Innodb 在 Repeatable Read 下通过 MVCC 提供了稳定的视图,因此 Innodb 的 RR 隔离级别下是不会出现上述幻读异常中的第一个场景的,但第二个场景还是会出现。

  4. 串行化 Serializable
    使用表级锁来保证所有事务的串行化,可以防止所有的异常情况,但是牺牲了系统的并发性。

查看隔离级别的命令为

SHOW VARIABLES LIKE 'transaction_isolation';
# 或者
SELECT @@global.tx_isolation, @@tx_isolation;
Salin selepas log masuk

第二种方式可以查看全局和当前会话的隔离级别。
Analisis terperinci transaksi MySQL
设置隔离级别的命令为

# 将当前会话的隔离级别设为读未提交
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
# 将全局的隔离级别设为读未提交
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
Salin selepas log masuk

结语

本文简单介绍了 MySQL 事务的语法和 ACID 特性,以及事务并发处理中可能出现的异常情况和为了防止这些异常而设计的事务隔离级别。有兴趣的朋友可以尝试在两个不同的 MySQL 客户端来模拟四种隔离级别下三种异常的发生情况,在之后的文章中,会继续深入探讨 MySQL 是如何实现隔离级别的。

推荐学习:mysql学习视频教程

Atas ialah kandungan terperinci Analisis terperinci transaksi MySQL. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:csdn.net
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan