MySQL事务
MySQL事务
什么是事务?
数据库中的事务是指对数据库执行的一批操作,在同一个事务当中,这些操作要么全部执行成功, 要么全部失败,不会存在部分成功的情况。
- 事务是 一个原子操作,是一个最小执行单元,可以由一个或者多个SQL语句构成。
- 在同一个事务当中,所有SQL语句都执行成功时整个事务成功,有一个SQL语句执行失败则整个事务执行失败。
事务的四大特性ACID
原子性(Atomicity)
事务是一个不可分割的工作单位,事务中的操作要么全部执行,要么全部不执行。 这确保了事务的完整性,防止了部分操作成功部分操作失败的情况。
- 事务是一个完整的操作,事务的各元素是不可分的。
- 事务中的所有元素必须作为一个整体提交或回滚。
- 如果事务中的任何元素失败,则整个事务失败。
一致性(Consistency)
事务前后数据的完整性必须保持一致。一个事务必须使数据库从一个一致性状态变成另一个一致性状态。 在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
隔离性(Isolation)
在并发环境中,当不同的事务同时操作相同的数据时,事务之间的操作不会互相影响。
- 对数据进行修改的所有并发事务是彼此隔离的,表面事务必须是独立的,不以任何方式依赖或影响其他事务。
- 修改数据的事务可以在另一个使用相同数据的事务开始之前或结束之后访问这些数据。
- 并发访问数据库时,一个用户的事务不被其他事务干扰,并发事务的数据库之间是独立的。
- 隔离级别:
- 未提交读:READ-UNCOMMITTED
- 提交读:READ-COMMITTED
- 可重复读:REPEATABLE-READ
- 串行化:SERIALIZABLE
持久性(Durability)
事务一旦提交,它对数据库中数据的更改就是永久性的,即使系统发生故障也不会丢失。
并发事务问题
并发事务是指在数据库系统中,多个事务同时对数据库进行读写和修改的过程。
对于同时允许的多个事务(多线程并发),当这些事务访问数据库中的相同数据时, 如果没有采取必要的隔离机制就会导致各种并发问题(线程安全问题 、共享内存问题)。
脏写/更新丢失
一个事务修改了另一个事务已经修改但还没有提交的数据,会导致数据不一致和丢失更新的问题。
第一类更新丢失:A,B 事务同时操作一个数据,A 更改完成还没提交,此时 B 更改失败回滚,会将 A 更新的数据也回滚。(事务撤销造成的撤销丢失)
第二类更新丢失:A,B 事务同时操作一个数据,A 更改完成还没提交,此时 B 更改并提交,覆盖了 A 更改的数据。(事务提交造成的覆盖丢失)
脏读
一个事务读到了另一个事务还未提交的数据。
A,B 事务同时操作一个数据,A 事务修改了某条数据但还未提交,此时B事务访问了该条数据读到的就是 A 修改过后的数据。 若 A 事务回滚,则 B 事务读到的就是脏数据,造成了数据不一致。
不可重复读
一个事务读到了另一个事务已经提交的更新数据,引起事务中多次查询结果不一致。
A,B 事务同时操作一个数据,A 先查询某条数据,在事务未结束时 B 事务对同一数据修改并提交, 此后 A 再次查询该条数据,两次查询的结果不同。
幻读
一个事务按相同查询条件重新读取以前检索过的数据,却发现其他事务插入了满足查询条件的新数据。
事务 A 在操作一堆数据的时候,事务 B 插入了一条新数据,事务 A 再次查询时,发现多了一条数据,像是幻觉。
事务隔离级别
提示
事务隔离级别越高,数据越安全,但是性能越差。
未提交读
允许脏读,即允许一个事务看到其他事务未提交的修改。 这种隔离级别最低,性能最高,但一致性最差。
提交读
只允许一个事务看到其他事务已经提交的修改。 这种隔离级别可以防止脏读,但不能防止可重复读和幻读。
可重复读(MySQL默认)
确保如果一个事务中执行多次相同的 select 语句得到的都是相同的结果。 这种隔离级别可以防止脏读和不可重复读,但不能完全防止幻读。
串行化
将事务完全隔离,使得它们按顺序执行。 这种隔离级别最高,一致性最好,但性能最差。