MySQL事务

目录

一、MySQL事务操作两种方式

1.1 显式事务控制(命令行方式)

1.2 关闭自动提交模式

二、JDBC事务管理实现

三、事务核心特性(ACID)

3.1 事务

3.2 事务的特性

3.3 不考虑事务的隔离性会引发的问题

3.4 事物的隔离级别


一、MySQL事务操作两种方式

1.1 显式事务控制(命令行方式)

-- 开启事务
START TRANSACTION;

-- 执行转账操作
UPDATE account SET money = money - 1000 WHERE name = '冠希';
UPDATE account SET money = money + 1000 WHERE name = '美美';

-- 根据执行结果选择提交或回滚(提交/回滚后该事务结束)
COMMIT;  -- 成功时提交
ROLLBACK; -- 出现异常时回滚

1.2 关闭自动提交模式

-- 查看当前自动提交状态
SHOW VARIABLES LIKE 'autocommit';  -- 默认值为ON

-- 关闭自动提交
SET autocommit = OFF;

-- 执行转账操作
UPDATE account SET money = money - 1000 WHERE name = '冠希';
UPDATE account SET money = money + 1000 WHERE name = '美美';

-- 手动提交
COMMIT;

-- 或回滚操作(只要不提交,该事务可多次执行回滚操作)
ROLLBACK;

-- 恢复默认设置或客户端窗口关闭后再次打开(上次设置自动失效)
SET autocommit = ON;

二、JDBC事务管理实现

package com.qcby.dao;

import com.qcby.utils.JdbcUtils2;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

public class TransferDao {
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        try {
            //jdbc连接数据库
            //1.加载驱动
            //2.获取连接(URL 用户名  密码)
            connection = JdbcUtils2.getConnection();

            //开启事务(关闭自动提交)
            connection.setAutoCommit(false);

            //3.编写sql
            String sql1="UPDATE account SET money = money - 1000 WHERE name = '冠希'";
            String sql2="UPDATE account SET money = money + 1000 WHERE name = '美美'";

            //4.获取执行sql的stmt的对象
            statement = connection.createStatement();
            int i=statement.executeUpdate(sql1);
            //int m=10/0;
            int i2=statement.executeUpdate(sql2);

            //提交事务
            connection.commit();
            System.out.println("转账成功!");

        } catch (SQLException e) {
            //回滚事务(如果发生异常)
            try {
                connection.rollback();
                System.out.println("转账失败,已回滚!");
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            System.out.println("转账失败,已回滚!");
            e.printStackTrace();
        }finally {
            //7.关闭资源(先开的后关 后开的先关)
            JdbcUtils2.close(connection, statement);
        }
    }
}

        若 int m=10/0; 该行代码正常执行,则返回除零异常,执行回滚操作,数据未发生改变;

        若代码正常执行,则返回转账成功,数据库执行对应操作。

三、事务核心特性(ACID)

3.1 事务

事务是进行逻辑处理的最小单元,要么全部成功执行,要么全部失败回滚。

3.2 事务的特性

1. 原子性:Atomicity,即表示事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败;

2. 一致性:Consistency,事务执行后,数据库状态与其它业务规则保持一致。例如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的;

3. 隔离性:Isolation,是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰;

4. 持久性:Durability,指的是一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。

3.3 不考虑事务的隔离性会引发的问题

1. 脏读(Dirty Read)

一个事务读取到了另一个事务未提交的数据。

举例(演示脏读

条件:READ UNCOMMITTED

操作步骤:

窗口A(事务1)窗口B(事务2)
set session transaction isolation level read uncommitted;start transaction;
start transaction;update account set money=money-1000 where name = '熊大';
select * from account; → 熊大9000,熊二10000update account set money=money+1000 where name = '熊二';

此时看到未提交的数据

rollback;(撤销操作)
select * from account;→ 数据恢复

现象:A读取到B未提交的临时数据,导致脏读。

2. 不可重复读

一个事务读取到了另一个事务提交的数据,导致了多次查询的结果不一致。强调的是update,修改记录的数据。

避免脏读和演示不可重复读

操作步骤:

窗口A(事务1)窗口B(事务2)

set session transaction isolation level read uncommitted;

start transaction;

start transaction;

update account set money=money-1000 where name = '熊大';

update account set money=money+1000 where name = '熊二';

select * from account; → 未读到B的修改

 commit;
select * from account;→ 提交后可见

现象:脏读被解决,但同一事务中多次查询结果不一致(不可重复读)。

避免不可重复读(REPEATABLE READ)

操作步骤:

窗口A

窗口B

set session transaction isolation level repeatable uncommitted;start transaction;
start transaction;

update account set money=money-1000 where name = '熊大';

update account set money=money+1000 where name = '熊二';

select * from account; → 查询到的数据未改变

 commit;

select * from account;→ 查询到的数据未改变(仍读取快照)
commit; 

select * from account;→ 查询到的数据改变

现象:事务内多次读取结果一致,但新增数据可能导致幻读。

3. 虚度(幻读 Phantom Read

一个事务读取到了另一个事务提交的数据,导致了多次查询的结果不一致。强调是insert,向表中添加一条数据。

幻读

条件:REPEATABLE READ
操作步骤:

窗口A

窗口B

start transaction;start transaction;

insert into account values (null,'杰克',1000);

select * from account; → 8条记录

commit;

select * from account; → 仍为8条记录

commit;

select * from account; → 新查询看到9条记录

现象:同一事务中两次查询结果集数量不同(MySQL通过MVCC部分解决幻读)。

避免各种读

操作步骤:

窗口A

窗口B

set session transaction isolation level serializable; 

start transaction;

start transaction;

insert into account values (null,'小苍',10000);

select * from account; →显示插入成功,但实际上并未成功,数据库数据未发生改变

commit;

select * from account; →新查询到数据库中的数据并未改变

现象:完全隔离,但并发性能最低。

3.4 事物的隔离级别

1. 事务的隔离级别

设置数据库的隔离级别,根据级别的不同,可以解决上述的读的问题。

  • Read uncommitted ‐‐ 什么都解决不了
  • Read committed ‐‐ 避免脏读,但是不可重复读和虚读有可能产生
  • Repeatable read ‐‐ 避免脏读和不可重复读,虚度有可能产生的
  • Serializable ‐‐ 避免各种读

2. 四种隔离级别有安全性和效率

  • 安全 Serializable > Repeatable read > Read committed > Read uncommitted
  • 效率 Serializable < Repeatable read < Read committed < Read uncommitted

3. 数据库默认的隔离级别

MySQL的数据库,默认的隔离级别是Repeatable read,避免脏读和不可重复读。

4. 总结

隔离级别

脏读

不可重复读

幻读

性能

Read uncommitted

最高

Read committed

Repeatable read

Serializable

最低

MySQL 事务是指一组数据库操作,这些操作要么全部执行,要么全部不执行,其目的是保证在并发环境下,数据的一致性和完整性。MySQL 事务具有 ACID 性质,即原子性、一致性、隔离性和持久性。 MySQL 中使用事务需要使用 BEGIN、COMMIT 和 ROLLBACK 语句,其中 BEGIN 表示开启一个事务,COMMIT 表示提交事务,ROLLBACK 表示回滚事务事务的基本语法如下: ``` BEGIN; -- 执行一组数据库操作 COMMIT; -- 提交事务 -- 或者 ROLLBACK; -- 回滚事务 ``` 在 MySQL 中,事务的隔离级别分为四个等级,分别是 Read Uncommitted、Read Committed、Repeatable Read 和 Serializable。隔离级别越高,数据的一致性和完整性越高,但同时也会影响数据库的性能。 MySQL 事务的 ACID 性质有以下含义: 1. 原子性(Atomicity):事务中的所有操作要么全部执行成功,要么全部失败回滚,不会只执行其中的一部分操作。 2. 一致性(Consistency):事务执行前后,数据库中的数据必须保持一致性状态,即满足数据库的约束条件和完整性规则。 3. 隔离性(Isolation):事务之间应该是相互隔离的,一个事务的执行不应该被其他事务干扰,保证事务之间的数据相互独立。 4. 持久性(Durability):事务提交后,对数据库的修改应该是永久性的,即使出现系统故障或电源故障,也不应该对数据产生影响。 总之,MySQL 事务是一组数据库操作,具有 ACID 性质,可以通过 BEGIN、COMMIT 和 ROLLBACK 语句来实现,隔离级别越高,数据的一致性和完整性越高,但同时也会影响数据库的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值