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.
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.
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
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)
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
// 正常执行,提交 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; # 事务回滚
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; # 释放保留点
顺便提一下,事务有隐式事务(自动提交)和显示事务(必须手动提交)两种,MySQL 默认为隐式事务,会进行自动提交,通过 autocommit
参数来控制。
# 查看变量 SHOW VARIABLES LIKE 'autocommit'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit | ON | +---------------+-------+ # 开启自动提交(默认) SET autocommit = 1; # 关闭自动提交 SET autocommit = 0;
在自动提交状态下,如果没有显示的开启事务,那每一条语句都是一个事务,系统会自动对每一条 sql 执行 commit 操作。使用 BEGIN 或 START TRANSACTION 开启一个事务之后,自动提交将保持禁用状态,直到使用 COMMIT 或 ROLLBACK 结束事务之后,自动提交模式会恢复到之前的状态。
关于事务还有另一个参数 completion_type
,默认取值为 0 (NO_CHAIN)
# 查看变量 SHOW VARIABLES LIKE 'completion_type'; +-----------------+----------+ | Variable_name | Value | +-----------------+----------+ | completion_type | NO_CHAIN | +-----------------+----------+
completion_type = 0: 默认值,执行 commit 后不会自动开启新的事务。
completion_type = 1: 执行 commit 时,相当于执行 COMMIT AND CHAIN,自动开启一个相同隔离级别的事务。
completion_type = 2: 执行 commit 时,相当于执行 COMMIT AND RELEASE,提交事务后自动断开服务器连接。
在实际产线环境下,可能会存在大规模并发请求的情况,如果没有妥善的设置事务的隔离级别,就可能导致一些异常情况的出现,最常见的几种异常为脏读(Dirty Read)
、幻读(Phantom Read)
和不可重复读(Unrepeatable Read)
。
脏读指一个事务访问到了另一个事务未提交的数据,如下过程:
不可重复读指一个事务多次读取同一数据的过程中,数据值 内容 发生了改变,导致没有办法读到相同的值,描述的是针对同一条数据 update/delete 的现象,如下过程:
幻读指一个事务多次读取同一数据的过程中,全局数据(如数据行数)发生了改变,仿佛产生了幻觉,描述的是针对全表 insert/delete 的现象,如下过程:
或者是另一种场景,比如对于有唯一性约束的字段(如 id),发生如下过程:
串行化的事务处理方式当然是最安全的,但是串行无法满足数据库高并发访问的需求,作为妥协,有时不得不降低数据库的隔离标准来换取事务的并发能力,通过在可控的范围内牺牲正确性来换取效率的提升,这种权衡通过事务的隔离级别来实现。
数据库有 4 种事务隔离级别,由低到高依次为 读未提交 Read Uncommitted
、读已提交 Read Committed
、可重复读 Repeatable Read
、串行化 Serializable
。
读未提交 Read Uncommitted
允许读取未提交的内容,这种级别下的查询不会加锁,因此脏读、不可重复读、幻读都有可能发生。
读已提交 Read Committed
只允许读取已提交的内容,这种级别下的查询不会发生脏读,因为脏数据属于未提交的数据,所以不会被读取,但是依然有可能发生不可重复读和幻读。
可重复读 Repeatable Read (MySQL 的默认隔离级别)
使用行级锁来保证一个事务在相同查询条件下两次查询得到的数据结果一致,可以避免脏读和不可重复读,但是没有办法避免幻读。
需要特殊注意的是,Innodb 在 Repeatable Read 下通过 MVCC 提供了稳定的视图,因此 Innodb 的 RR 隔离级别下是不会出现上述幻读异常中的第一个场景的,但第二个场景还是会出现。
串行化 Serializable
使用表级锁来保证所有事务的串行化,可以防止所有的异常情况,但是牺牲了系统的并发性。
查看隔离级别的命令为
SHOW VARIABLES LIKE 'transaction_isolation'; # 或者 SELECT @@global.tx_isolation, @@tx_isolation;
第二种方式可以查看全局和当前会话的隔离级别。
设置隔离级别的命令为
# 将当前会话的隔离级别设为读未提交 SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; # 将全局的隔离级别设为读未提交 SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
本文简单介绍了 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!