💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
是数据库区别于文件系统的重要特性之一,用于保证数据库的完整性,数据库会从一种一致性状态转换为另一种一致性状态。 1、四大特性 (1) 原子性 数据库的每个事务都是不可分割的单元,只有事务中的所有 SQL 语句都执行成功,才算整个事务成功,如果事务中有一个 SQL 语句执行失败,整个事务都将回滚。 (2) 一致性 数据库从一种一致性状态转换为另一种一致性状态,即数据库的完整性约束没有被破坏,要么都是新数据,要么都是老数据。 (3) 隔离性 一个事务的影响在该事务提交之前对其他事务都是不可见的,通过锁机制来实现。 (4) 持久性 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。 2、语法: 在 MySQL 命令行默认设置下,事务是自动提交的,即执行了 SQL 语句之后马上会执行 commit 操作,可以通过 set autocommit = 0 来禁用当前会话的自动提交。 (1) 开始事务 begin 或 start transaction (2) 提交事务 commit,即 commit [work] (3) 事务回滚 rollback,即 rollback [work] (4) 定义保存点 savepoint xxx,一个事务中可以有多个保存点 (5) 删除保存点 release savepoint xxx,保存点不存在时会抛出异常 (6) 回滚到某个保存点 rollback to [savepoint] xxx 回滚到某个保存点并不能让事务结束,要提交事务或回滚事务。 3、InnoDB 的实现 隔离性由锁机制实现,原子性、一致性、持久性都是通过数据库的 redo 日志和 undo 日志来完成。 redo 日志:重做日志,它记录了事务的行为; undo 日志:对数据库进行修改时会产生 undo 日志,也会产生 redo 日志,使用 rollback 请求回滚时通过 undo 日志将数据回滚到修改前的样子。 InnoDB 存储引擎回滚时,它实际上做的是与之前相反的工作,insert 对应 delete,delete 对应insert,update 对应相反的 update。 ps: 1、commit 和 commit work 的区别 commit work 可以控制事务接收后的行为,可以用 select @@completion_type 查看值,默认是0。 completion_type = 0,两者等价。 completion_type = 1,commit work 等价于 commit and chain,表示马上开启一个相同隔离级别的事务。 completion_type = 2,commit work 等价于 commit and release,表示事务提交后自动断开与服务器的连接。 2、隐式提交 有些语句会造成隐式提交,主要有3类: (1) DDL 语句:create event、create index、alter table、create database、truncate 等等,所有 DDL 语句都是不能回滚的。 (2) 权限操作语句:create user、drop user、grant、rename user 等等。 (3) 管理语句:analyze table、check table 等等。 3、隔离级别 通过锁机制实现,大部分数据库都没有提供真正意义上的隔离性。 数据库制造商在标准和性能之间进行了权衡,MySQL 还是比较贴近该标准的,ISO 和 ANSI SQL 标准了四种事务隔离级别的标准。 可以用 select @@tx_isolation 来查看它的值。 (1) read uncommitted 隔离级别最低,开销也是最小,目前没有数据库会设置它为默认隔离级别,因为会出现脏读。 脏读:读到未提交的数据(脏数据),n 事务中读到 m 事务中修改了,但未提交的数据,即在不同事务下可以读到其它事务未提交的数据。 严格来说,它已经破坏了事务的隔离性。 (2) read committed 它不允许在别的事务未提交时读取到别的事务的修改数据,容易出现不可重复读,但是可以被人们接受,因为事务已经提交,数据已经持久化到磁盘了,隔离级别越低,事务请求的锁就越少,或者保持锁定的时间就越短,这也是大多数数据库默认的事务隔离级别都是 read committed 的原因。 不可重复读:在一个事务中多次读同一个数据,由于其他事务在第一个事务还没结束时修改了数据,造成第一个事务中两次读到的数据不一致。 脏读与不可重复读:脏读读取的是未提交的数据,不可重复读读到的是已提交的数据。 (3) repeatable read InnoDB 存储引擎默认支持的隔离级别。不会出现脏读、不可重复读和幻读(InnoDB 避免了该问题)。 (4) serializable SQL 和 SQL2 标准的默认事务隔离级别,它是真正意义上的隔离,当然性能也是最差。 设置事务隔离级别: set [global|session] transaction isolation level {read uncommitted|...}; 比如:set tx_isolation='read-committed';