数据库事务
事务介绍
数据库事务(Database Transaction)是指将一系列操作整合在一起作为一个操作执行,要么全部成功完成,要么全部失败回滚,以保证数据的一致性和完整性。它存在的意义就是保证系统中的数据是正确的,不同数据间不会产生矛盾,也就是保证数据状态的一致性(Consistency)。
数据什么时候会发生矛盾呢?
看一下“Uzi”给“Mlxg”通过银行账号转账100元点外卖的流程(重点是转账):
- Uzi 银行账号扣除100元
- 给 Mlxg 账号增加100元
如果在 Uzi 账号扣除100元后,要给 Mlxg 增加时100元时,系统发生了故障最终导致 Mlxg 的100元没到账,但此时 Uzi 的账号中已经少了100元,这种故障就破坏了数据的一致性。最后导致 Mlxg 没钱点外卖。
通过事务就可以将步骤1和步骤2整合在一起执行,要么全部成功完成,要么全部失败回滚。
- 开始事务
START TRANSACTION;
- 扣除 Uzi 的金额,并记录日志。
- 向 Mlxg 增加相应金额,并记录日志。
- 提交事务
COMMIT;
(如果所有步骤都成功执行) - 如果任何一步出现问题,例如由于账户余额不足而无法完成转账,可以回滚事务
ROLLBACK;
,使所有操作都无效。
创建事务
在MySQL中,可以使用以下步骤来创建和管理事务:
启动事务(Start Transaction):
使用START TRANSACTION
或BEGIN
语句来启动一个新的事务。例如:1
START TRANSACTION;
执行事务操作(Perform Transaction Operations):
在事务中执行需要的数据库操作,如插入、更新或删除数据。例如:1
2
3INSERT INTO table_name (column1, column2) VALUES (value1, value2);
UPDATE table_name SET column1 = value1 WHERE condition;
DELETE FROM table_name WHERE condition;提交事务(Commit Transaction):
如果事务中的所有操作都成功完成,并且要将更改永久保存到数据库中,可以使用COMMIT
语句来提交事务。例如:1
COMMIT;
回滚事务(Rollback Transaction):
如果在事务过程中发生了错误或者需要撤销已经进行的更改,可以使用ROLLBACK
语句来回滚事务,将数据库恢复到事务开始前的状态。例如:1
ROLLBACK;
回滚点(Rollback Point):
可以使用SAVEPOINT sp
语句来设置回滚点,通过ROLLBACK TO SAVEPOINT sp
来回滚到指定位置。例如:1
2SAVEPOINT sp;
ROLLBACK TO SAVEPOINT sp;
需要注意的是,默认情况下,MySQL将每个SQL语句视为一个单独的事务,也就是自动提交模式(Autocommit)。如果想要手动控制事务的提交和回滚,则需要关闭自动提交模式,通过设置 autocommit
变量为0来实现:
1 | SET autocommit = 0; |
此时,每个事务的开始和结束需要显式地使用 START TRANSACTION
、COMMIT
和 ROLLBACK
来控制。
例如:
1 | SET autocommit = 0;-- 关闭自动提交START TRANSACTION;-- 启动事务-- 执行事务操作INSERT INTO table_name (column1, column2) VALUES (value1, value2); |
通过以上步骤,你可以在MySQL中创建和管理事务。
事务四大特性
MySQL(以及其他数据库管理系统)的事务具有四个核心特性,通常被称为ACID特性:
- 原子性(Atomicity):
原子性确保事务中的所有操作要么全部成功执行,要么全部失败回滚。它将多个操作视为一个不可分割的单元,如果其中任何一个操作失败,整个事务将被回滚到起始状态,撤销所有的修改。 - 隔离性(Isolation):
隔离性确保并发执行的事务之间相互隔离,使它们看起来像是按顺序一个接一个地执行。每个事务都应该在不受其他并发事务干扰的情况下执行。这样可以防止数据损坏或不一致性问题。 - 持久性(Durability):
持久性确保一旦事务提交,其对数据库的修改将永久保存,即使发生系统故障或重启。已提交的事务的更改应该持久地存储在数据库中,以便在任何情况下都能进行恢复。 - 一致性(Consistency):
一致性要求事务在执行前后数据库必须处于一致的状态。这意味着事务的执行不会破坏数据库的完整性约束和业务规则。如果事务成功提交,数据库应该处于有效、合法的状态。
实际上事务的原子性、隔离性和持久性是实现一致性的手段或者说方法,真正的目的是保证数据库事物的一致性,所以在学习事务时应该重点关注数据库是如何保证A、I、D特性。
事务隔离级别
事务隔离级别是指在多个并发事务同时进行读写操作时,数据库管理系统如何保证它们之间的数据隔离性。MySQL 提供了四个标准的事务隔离级别,分别是:
- 读未提交(Read Uncommitted):
最低级别的隔离级别。事务可以读取其他事务尚未提交的数据,可能会导致脏读(Dirty Read)、不可重复读(Non-repeatable Read)和幻读(Phantom Read)的问题。 - 读已提交(Read Committed):
事务只能读取其他事务已经提交的数据。这样可以避免脏读,但是依然可能会遇到不可重复读和幻读的问题。 - 可重复读(Repeatable Read):
默认的隔离级别。事务在整个过程中可以多次读取同样的数据,并且保证在事务结束前,其他事务对该数据进行的修改不会被读取到。这样可以避免脏读和不可重复读,但仍然可能出现幻读的问题。 - 串行化(Serializable):
最高级别的隔离级别。事务按顺序逐个执行,完全隔离了并发事务。它避免了所有的并发问题,但是在高并发环境下可能会导致性能问题。
可以通过 SET TRANSACTION ISOLATION LEVEL
语句来设置事务隔离级别,例如:
1 | SET TRANSACTION ISOLATION LEVEL READ COMMITTED; |
需要注意的是,隔离级别越高,数据的一致性和安全性越好,但同时也增加了并发性能的开销。
Mysql默认的事务隔离级别是可重复读(Repeatable Read)
Oracle,SqlServer中都是选择**读已提交(Read Commited)**作为默认的隔离级别