事务

事务

事务的应用场景说明:在实际的开发过程中,一个业务操作如:转账,往往是要多次访问数据库才能完成的。转账是一个用户扣钱,另一个用户加钱。如果其中有一条 SQL 语句出现异常,这条 SQL 就可能执行失败。事务执行是一个整体,所有的 SQL 语句都必须执行成功。如果其中有 1 条 SQL 语句出现异常,则所有的SQL 语句都要回滚,整个业务执行失败。

事务概念:

如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。

事务开启之后, 所有的操作都会临时保存到事务日志中, 事务日志只有在得到 commit 命令才会同步到数据表中,其他任何情况都会清空事务日志(rollback,断开连接)

事务的操作:

  1. 开启事务: start transaction;

  2. 回滚:rollback;

  3. 提交:commit;

    例子:
    CREATE TABLE account (
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(10),
    balance DOUBLE
    );

    -- 添加数据
    INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);

模拟张三给李四转 500 元钱,一个转账的业务操作最少要执行下面的 2 条语句:

张三账号-500

李四账号+500

-- 张三账号-500

update account set balance = balance - 500 where name='zhangsan';

-- 李四账号+500

update account set balance = balance + 500 where name='lisi';

假设当张三账号上-500 元,服务器崩溃了。李四的账号并没有+500 元,数据就出现问题了。我们需要保证其中

一条 SQL 语句出现问题,整个转账就算失败。只有两条 SQL 都成功了转账才算成功。这个时候就需要用到事务。

事务提交的两种方式:

1)自动提交:

​ MySQL数据库中事务默认自动提交; 一条DML(增删改)语句会自动提交一次事务。

2)手动提交:

​Oracle 数据库默认是手动提交事务;需要先开启事务,再提交

开启事务:start transaction;

提交事务:commit;

回滚事务:rollback;

手动提交事务使用过程:

  1. 执行成功的情况: 开启事务 ->执行多条 SQL 语句 ->成功提交事务

  2. 执行失败的情况: 开启事务 -> 执行多条 SQL 语句-> 事务的回滚

修改事务的默认提交方式:

​ 查看事务的默认提交方式:SELECT @@autocommit; -- 1 代表自动提交 0 代表手动提交
​ 修改默认提交方式: set @@autocommit = 0;

模拟张三给李四转 500 元钱(成功) 目前数据库数据如下:
事务

  1. 执行以下 SQL 语句: 1.开启事务, 2.张三账号-500, 3.李四账号+500

-- 张三账号-500
update account set balance = balance - 500 where name='zhangsan';
-- 李四账号+500
update account set balance = balance + 500 where name='lisi';

  1. 使用navicat查看数据库:发现数据并没有改变

  2. 在控制台执行 commit 提交事务:

  3. 使用 navicat 查看数据库:发现数据改变

事务的四大特征:

1.原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。事务中所有的 SQL 语句要么都执行成功,要么都失败

2.持久性:当事务提交或回滚后,数据库会持久化的保存数据。一旦事务执行成功,对数据库的修改是持久的。就算关机,也是保存下来的。

3.隔离性:多个事务之间。相互独立。事务与事务之间不应该相互影响,执行时保持隔离的状态。

4.一致性:事务操作前后,数据总量不变.如:转账前2个人的总金额是2000,转账后总金额也是2000

事务的隔离级别(了解)

概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
存在问题:
1.脏读:一个事务,读取到另一个事务中没有提交的数据
2.不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。这是事务update时引发的问题
3.幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。一个事务中2次读取到的数据量不一致,要求的是一个事务在多次读取到的数据量一致,这是insert和delete引发的问题

隔离级别:(隔离级别从小到大安全性越来越高,但是效率越来越低)

1.read uncommitted:读未提交 :产生的问题:脏读、不可重复读、幻读

2.read committed:读已提交 (Oracle):产生的问题:不可重复读、幻读

3.repeatable read:可重复读 (MySQL默认):产生的问题:幻读

4.serializable:串行化:可以解决所有的问题,事务还未提交锁表,不允许事务查询;提交之后,事务可以查询

数据库查询隔离级别: select @@tx_isolation;

数据库设置隔离级别:set global transaction isolation level 级别字符串;

上一篇:河北银行热烈祝贺敬业集团荣登世界500强


下一篇:MySQL 事务