事务的概述
想象一下,你经营一家银行,这家银行有两个客户,Alice 和 Bob。Alice 要给 Bob 转账100元。在现实生活中,这似乎是一个简单的操作,但在数据库的世界里,这涉及到一系列复杂的步骤,这就是我们的事务处理要发挥作用的地方。
故事背景
假设我们有一个数据库表 accounts
,它记录了客户的账户余额:
CREATE TABLE accounts (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
balance DECIMAL(10, 2) -- 余额
);
INSERT INTO accounts (name, balance) VALUES ('Alice', 1000.00);
INSERT INTO accounts (name, balance) VALUES ('Bob', 500.00);
在这个故事中,Alice 想要给 Bob 转账100元。这个过程必须被视为一个单一的操作;换句话说,要么完全发生,要么完全不发生。我们不希望因为某个步骤失败而导致 Alice 的账户减少了100元,而 Bob 的账户却没有相应增加。
使用MySQL事务
为了完成这个操作,我们将使用MySQL事务。事务是一个将多个步骤包装为单个操作的过程,确保所有步骤都成功完成,否则什么也不做。
步骤 1: 开启事务
START TRANSACTION;
想象一下你告诉银行系统:“嘿,我要开始一个很重要的操作,请确保要么所有事情都按计划进行,要么什么都不做。”
步骤 2: 执行操作
接下来,我们需要从Alice的账户中扣除100元,并将其添加到Bob的账户中。
UPDATE accounts SET balance = balance - 100 WHERE name = 'Alice';
UPDATE accounts SET balance = balance + 100 WHERE name = 'Bob';
这就像是从Alice的钱包中拿出100元,走过去,再放到Bob的钱包里。但在银行的世界里,我们需要确保这两个步骤要么一起成功,要么一起失败。
步骤 3: 提交事务
如果一切顺利,我们就可以确认这个操作了。
COMMIT;
这就好比你对银行系统说:“一切顺利,请正式记录下这次操作。”
如果出错怎么办?
但是,如果在转账过程中出现任何问题(比如突然发现Alice的账户余额不足),我们需要撤销所有操作,就好像什么都没有发生过一样。
ROLLBACK;
这就相当于说:“哎呀,出错了,让我们假装这次操作从未发生过。”
结论
通过使用事务,我们可以确保数据的一致性和完整性,即使在执行多步操作时也能保证数据不会处于不一致的状态。就像在现实生活中管理银行账户一样,事务让数据库操作既安全又可靠,确保了我们的金融交易既准确又高效。
在数据库管理系统中,事务的处理非常关键,尤其是当多个用户或应用同时操作数据库时。为了更好地理解事务的复杂性和重要性,我们可以继续扩展我们的银行故事,引入一些新的角色和情节,从而探讨事务的四大特性(ACID)、隔离级别以及并发问题。
事务的四大特性(ACID)
-
原子性(Atomicity): 这意味着事务中的所有操作要么全部完成,要么全部不完成。就像Alice向Bob转账,这个过程要么完全成功,Alice的账户减少而Bob的账户增加,要么失败时两个账户都保持不变。
-
一致性(Consistency): 确保数据库在事务前后都保持一致状态。例如,如果Alice和Bob的总资产在转账前是1500元,那么无论转账成功与否,他们的总资产在转账后仍然应该是1500元。
-
隔离性(Isolation): 当多个事务同时进行时,一个事务的操作不应影响其他事务。想象如果同时有两个转账操作,一个是Alice向Bob转账,另一个是Charlie向Dan转账,这两个操作应当互不干扰。
-
持久性(Durability): 一旦事务完成,它对数据库的修改就是永久性的,即使系统发生故障也不会丢失。
事务的隔离级别
隔离级别定义了一个事务可能受其他并发事务影响的程度。隔离级别从低到高依次是:
-
读未提交(Read Uncommitted): 允许事务读取未被其他事务提交的数据。这可能导致“脏读”问题。
-
读提交(Read Committed): 保证一个事务只能读取到其他事务已提交的数据。这有助于避免脏读,但仍可能遇到“不可重复读”问题。
-
可重复读(Repeatable Read): 确保在事务内多次读取同样的数据结果是一致的,即使在这段时间内其他事务对这些数据做了更新。这有助于避免不可重复读,但可能遇到“幻读”问题。
-
串行化(Serializable): 最高的隔离级别,通过强制事务串行执行,避免了脏读、不可重复读和幻读问题。但这也大大降低了并发性能。
事务的并发问题
在并发环境下,事务可能会遇到几个典型问题:
- 脏读(Dirty Reads): 一个事务读取到了另一个事务未提交的数据。
- 不可重复读(Non-Repeatable Reads): 在同一个事务内,多次读取同一数据集合时,由于其他事务的提交,使得某些行被修改或删除。
- 幻读(Phantom Reads): 一个事务重新读取一个范围的记录时,发现另一个事务插入了满足该查询范围的新记录。
结语
通过掌握事务的ACID特性、理解不同的隔离级别以及意识到并发操作可能带来的问题,数据库管理员和开发者可以设计出既能保证数据一致性和完整性,又能提高系统并发能力的数据库应用。就像在银行故事中,我们需要确保每个客户的资金安全,同时也希望银行能高效地处理多个客户的请求。
select @@transaction_isolation; /*查看当前的事务等级*/
set [session | global] transaction isolation level [read uncommitted |read committed|repeatable read| serializable]
你不看ppt去想也能想明白,因为你要修改表结构不等所有事务都提交的话保证不了数据的一致性