跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
数据库事务
”︁(章节)
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= 数据库事务 = '''数据库事务'''(Database Transaction)是数据库管理系统中的一个核心概念,它代表一组数据库操作,这些操作要么全部成功执行,要么全部不执行,确保数据库从一个一致状态转移到另一个一致状态。事务是保证数据完整性和一致性的关键机制。 == 事务的特性(ACID) == 事务具有四个基本特性,通常称为ACID特性: * '''原子性(Atomicity)''':事务是不可分割的工作单位,事务中的操作要么全部执行,要么全部不执行。 * '''一致性(Consistency)''':事务执行前后,数据库从一个一致状态转移到另一个一致状态。 * '''隔离性(Isolation)''':多个事务并发执行时,一个事务的执行不应影响其他事务的执行。 * '''持久性(Durability)''':一旦事务提交,其对数据库的修改就是永久性的,即使系统故障也不会丢失。 == 事务的基本操作 == 在SQL中,事务通常通过以下命令控制: * <code>BEGIN TRANSACTION</code> 或 <code>START TRANSACTION</code>:开始一个事务。 * <code>COMMIT</code>:提交事务,使事务的修改永久生效。 * <code>ROLLBACK</code>:回滚事务,撤销事务中的所有操作。 === 示例 === 以下是一个简单的事务示例,展示如何在SQL中执行事务操作: <syntaxhighlight lang="sql"> -- 开始事务 BEGIN TRANSACTION; -- 执行操作 UPDATE accounts SET balance = balance - 100 WHERE user_id = 1; UPDATE accounts SET balance = balance + 100 WHERE user_id = 2; -- 检查是否有错误 -- 如果没有错误,提交事务 COMMIT; -- 如果有错误,回滚事务 -- ROLLBACK; </syntaxhighlight> == 事务的隔离级别 == 数据库系统支持不同的事务隔离级别,以控制事务之间的可见性和影响。常见的隔离级别包括: * '''读未提交(Read Uncommitted)''':允许读取未提交的数据变更,可能导致脏读。 * '''读已提交(Read Committed)''':只允许读取已提交的数据,避免脏读,但可能出现不可重复读。 * '''可重复读(Repeatable Read)''':确保在同一事务中多次读取同一数据的结果一致,避免不可重复读,但可能出现幻读。 * '''串行化(Serializable)''':最高隔离级别,完全隔离事务,避免脏读、不可重复读和幻读,但性能较低。 === 设置隔离级别 === 在SQL中,可以通过以下语句设置事务的隔离级别: <syntaxhighlight lang="sql"> SET TRANSACTION ISOLATION LEVEL READ COMMITTED; </syntaxhighlight> == 事务的实际应用场景 == 事务在以下场景中尤为重要: 1. '''银行转账''':确保从一个账户扣款和另一个账户入账同时成功或失败。 2. '''订单处理''':确保订单创建、库存扣减和支付处理作为一个整体执行。 3. '''数据批量导入''':确保所有数据要么全部导入成功,要么全部不导入。 === 银行转账案例 === 以下是一个银行转账的完整事务示例: <syntaxhighlight lang="sql"> BEGIN TRANSACTION; -- 检查账户1是否有足够余额 DECLARE @balance DECIMAL(10,2); SELECT @balance = balance FROM accounts WHERE account_id = 1; IF @balance >= 100 BEGIN -- 扣款 UPDATE accounts SET balance = balance - 100 WHERE account_id = 1; -- 入账 UPDATE accounts SET balance = balance + 100 WHERE account_id = 2; COMMIT; PRINT '转账成功'; END ELSE BEGIN ROLLBACK; PRINT '余额不足,转账失败'; END </syntaxhighlight> == 并发事务与锁 == 当多个事务并发执行时,数据库系统使用锁机制来保证隔离性。常见的锁类型包括: * '''共享锁(Shared Lock)''':允许多个事务同时读取数据,但阻止其他事务获取排他锁。 * '''排他锁(Exclusive Lock)''':阻止其他事务获取共享锁或排他锁,用于写操作。 === 锁的示例 === <mermaid> sequenceDiagram participant T1 as 事务1 participant DB as 数据库 participant T2 as 事务2 T1->>DB: 获取行X的共享锁(SELECT) T2->>DB: 尝试获取行X的排他锁(UPDATE) DB-->>T2: 等待(因为T1持有共享锁) T1->>DB: 提交,释放锁 DB->>T2: 获取排他锁,继续执行 </mermaid> == 事务的保存点 == 在复杂事务中,可以设置保存点(Savepoint)来部分回滚事务: <syntaxhighlight lang="sql"> BEGIN TRANSACTION; -- 操作1 INSERT INTO orders (order_id, customer_id) VALUES (1, 101); -- 设置保存点 SAVEPOINT sp1; -- 操作2 UPDATE inventory SET quantity = quantity - 1 WHERE product_id = 5; -- 如果操作2失败,回滚到保存点 ROLLBACK TO sp1; -- 继续其他操作 COMMIT; </syntaxhighlight> == 分布式事务 == 在分布式系统中,事务可能涉及多个数据库或服务,此时需要使用分布式事务协议(如两阶段提交)来保证ACID特性。 === 两阶段提交(2PC) === <mermaid> graph TD A[协调者] -->|准备请求| B[参与者1] A -->|准备请求| C[参与者2] B -->|准备就绪| A C -->|准备就绪| A A -->|提交命令| B A -->|提交命令| C </mermaid> == 常见问题与解决方案 == * '''死锁''':多个事务互相等待对方释放锁。解决方案包括设置超时、按固定顺序获取锁等。 * '''长事务''':长时间运行的事务会占用资源。解决方案是拆分大事务为小事务。 * '''性能影响''':高隔离级别可能影响性能。解决方案是根据业务需求选择适当的隔离级别。 == 数学基础 == 事务的原子性可以用以下公式表示: <math> T = \{O_1, O_2, ..., O_n\} \\ \text{要么 } \forall O_i \in T, O_i \text{ 都执行} \\ \text{要么 } \forall O_i \in T, O_i \text{ 都不执行} </math> == 总结 == 数据库事务是保证数据一致性的关键机制,理解ACID特性、隔离级别和锁机制对于设计可靠的数据库应用至关重要。通过合理使用事务,可以确保即使在系统故障或并发访问的情况下,数据也能保持一致状态。 [[Category:计算机科学]] [[Category:数据库与信息系统]] [[Category:数据库基础]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)