做网站建设的平台,公司网站还有用吗,网站自助建设平台有哪些,网页美工设计软件什么是事务
在数据库中#xff0c;事务#xff08;Transaction#xff09;是指一组数据库操作#xff0c;这些操作要么全部成功执行#xff0c;要么全部失败回滚#xff0c;是保证数据库操作一致性的基本单位。事务具有原子性#xff08;Atomicity#xff09;、一致性…什么是事务
在数据库中事务Transaction是指一组数据库操作这些操作要么全部成功执行要么全部失败回滚是保证数据库操作一致性的基本单位。事务具有原子性Atomicity、一致性Consistency、隔离性Isolation和持久性Durability四个特性。
事务的特性
原子性Atomicity 原子性是指事务中的所有操作要么全部成功完成要么全部回滚到事务开始前的状态。即事务中的所有操作要么全部执行要么全部不执行不会出现执行了一半的情况。
一致性Consistency 一致性是指事务执行前后数据库的完整性约束没有被破坏。在事务开始和结束时数据库的完整性约束都得到保持比如外键约束、唯一性约束等。
隔离性Isolation 隔离性是指多个事务并发执行时彼此之间是相互隔离的一个事务的执行不应该受到其他事务的干扰。即使多个事务同时访问同一个数据也不能相互影响每个事务感觉自己独立地操作数据。为了保证隔离性数据库系统采用了多种隔离级别如下文所述。
持久性Durability 持久性是指事务一旦提交成功对数据库的修改就是永久性的不会因为数据库崩溃或其他原因导致数据丢失。即使系统发生故障也能够保证数据不会丢失。 隔离级别 隔离级别是指多个事务并发执行时一个事务对数据的修改对其他事务的可见程度。常见的隔离级别有四种分别是读未提交Read uncommitted、读已提交Read committed、可重复读Repeatable read和串行化Serializable。 读未提交Read uncommitted 读未提交是最低的隔离级别一个事务可以读取其他事务未提交的数据可能会导致脏读Dirty read问题即读到了其他事务已经修改但未提交的数据。
读已提交Read committed 读已提交是指一个事务只能读取已经提交的其他事务的数据可以避免脏读问题。但是由于其他事务正在执行所以可能出现不可重复读Non-repeatable read问题即同一个事务内读取同一数据两次结果不一致。
可重复读Repeatable read 可重复读是指同一个事务内多次读取同一数据时结果是一致的即使其他事务修改了该数据也不会对该事务造成影响。可重复读可以避免不可重复读问题但是可能会出现幻读Phantom read问题即同一个事务内两次查询结果不一致因为其他事务在此期间插入了符合条件的数据。
串行化Serializable 串行化是最高的隔离级别强制所有事务串行执行避免了脏读、不可重复读和幻读等问题。但是由于强制串行执行导致并发性能非常差一般不推荐使用。 为什么要使用事务 使用事务的主要目的是保证数据库中的数据一致性和完整性。在现实生活中许多业务场景都需要保证多个操作作为一个整体进行而不是单独执行这时候就需要使用事务来保证这些操作的原子性也就是要么全部执行成功要么全部失败保证数据的一致性。
举个例子假设我们要从银行账户A向账户B转账100元。这个过程需要进行两个操作将账户A的余额减去100元将账户B的余额增加100元。如果没有事务保证当这两个操作分别执行时如果在这两个操作之间发生了系统崩溃、网络中断等异常情况就有可能导致A账户扣款成功但B账户未收到款项从而导致数据的不一致性。使用事务可以保证这两个操作作为一个整体进行如果在操作过程中出现异常可以回滚事务保证数据的完整性。
此外使用事务还可以避免多个客户端并发修改同一个数据造成的数据冲突问题比如脏读、不可重复读、幻读等。通过设置不同的隔离级别可以平衡并发性能和数据一致性之间的关系。
因此使用事务可以有效保证数据库中数据的一致性和完整性同时避免多个客户端并发修改同一个数据造成的数据冲突问题。
案例演示 展示如何使用事务来保证一组 SQL 操作的原子性。 假设我们有两个表一个是用户表 user一个是订单表 order其中订单表记录了每个用户的订单信息。现在我们要实现一个功能当用户下单时需要先将用户的余额扣减相应的金额然后再在订单表中插入一条订单记录。
首先我们创建表
CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,balance DECIMAL(10, 2) NOT NULL DEFAULT 0.00
);CREATE TABLE order (id INT PRIMARY KEY AUTO_INCREMENT,user_id INT NOT NULL,amount DECIMAL(10, 2) NOT NULL,created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);接下来我们可以使用以下的 SQL 语句来实现这个功能
START TRANSACTION; -- 开始事务UPDATE user SET balance balance - 100.00 WHERE id 1; -- 扣减用户余额INSERT INTO order (user_id, amount) VALUES (1, 100.00); -- 插入订单记录COMMIT; -- 提交事务在上面的代码中我们首先使用 START TRANSACTION 开始一个事务然后执行扣减用户余额的操作和插入订单记录的操作最后使用 COMMIT 提交事务。如果在执行这些操作的过程中发生了任何错误我们可以使用 ROLLBACK 回滚事务保证数据的完整性和一致性。 需要注意的是如果使用 InnoDB 引擎MySQL 默认的隔离级别是 REPEATABLE READ。这种隔离级别可以避免脏读、不可重复读、幻读等问题但是也可能导致性能问题。如果需要平衡并发性能和数据一致性可以考虑使用更低的隔离级别比如 READ COMMITTED 或 READ UNCOMMITTED。