跳到正文
Kale的数字花园
目录 文章
/5 分钟/5 阅读/0 评论

事务理解

什么是事务: **指逻辑上一组操作,要么同时成功,要么同时失败。** jdbc中的事务是通过Connection对象进行事务管理的 没有事务 手动事务 需求:向数据库发送10000条数据,每1000条是合理的 如果不考虑事务的隔离性,将会产

什么是事务: 指逻辑上一组操作,要么同时成功,要么同时失败。

举例: 转账 a 给b 转账 100  a原来有1000 b原来也有1000
account 是一个表名 表示的 账务表,里面有人的信息,和人的金额。
update account set money=money-100 where name = a;
update account set money =money+100 where name=b;

假设:
update account set money=money-100 where name = a;
出现了异常。
update account set money =money+100 where name=b;
后果: a的余额是900   b的余额 1000

有了事务:

开启事务:
update account set money=money-100 where name = a;
出现了异常。 ---- 事务进行管理: 进行回滚: 更改的记录无效。
update account set money =money+100 where name=b;

此时:a的余额是1000  b的余额 1000

mysql中事务

-- mysql中,默认事务是自动提交的。一条sql一个事务。

开启事务
操作
提交事务;


start transaction  -- 开启一个事务。以后的sql都在一个事务中。更改的内容不会自动提交。
rollback        -- 事务的回滚—同时失败的情况。--事务结束,并且全部失败,数据回复到开始之前的状态
commit -- 事务的提交----同时成功---事务结束。全部成功。

-- 账务信息
create table account(
	name varchar(10),
	money double
);

insert into account(name,money) values('a',1000);
insert into account(name,money) values('b',1000);

去做a给b转100块。

-- mysql默认类似这样
start transaction ;
update account set money = money -100 where name = ‘a’;
commit;
start transaction ;
update account set money = money +100 where name = ‘b’;
commit;

-- 自身手动控制事务。
start transaction ;
update account set money = money -100 where name = ‘a’;

update account set money = money +100 where name = ‘b’;
commit;

代码实现

jdbc事务管理

API方法

jdbc中的事务是通过Connection对象进行事务管理的

conn.setAutoCommit(flase)//相当于start transaction  开启事务
conn.rollback(); //rollback  事务回滚
conn.commit(); //commit   事务提交

代码实现

没有事务

/**
     * 案例:jack 给  rose 转帐     没有事务
     */
    @Test
    public void test1()  {

        Connection conn = null;
        Statement stmt = null;
        try {
            conn = JDBCUtil.getConnection();

            stmt = conn.createStatement();

            String sql ="update account set money = money -100 where name = 'jack'";
            stmt.executeUpdate(sql);

            //人为的给出一个异常
            int a = 10/0;

            String sql2 ="update account set money = money +100 where name = 'rose'";
            stmt.executeUpdate(sql2);

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JDBCUtil.close(stmt,conn);
        }
    }

手动事务

/**
     * 案例:jack 给  rose 转帐     添加事务
     */
    @Test
    public void test2()  {

        Connection conn = null;
        Statement stmt = null;
        try {
            conn = JDBCUtil.getConnection();

            //[开启事务]
            conn.setAutoCommit(false);

            //[操作数]
            stmt = conn.createStatement();

            String sql ="update account set money = money -100 where name = 'jack'";
            stmt.executeUpdate(sql);

            //人为的给出一个异常
            int a = 10/0;

            String sql2 ="update account set money = money +100 where name = 'rose'";
            stmt.executeUpdate(sql2);

            //没有问题,就提交
            conn.commit();

        } catch (SQLException e) {
            //如果中间发生的异常,回滚到前面的操作
            try {
                conn.rollback();
                conn.commit();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }

            e.printStackTrace();
        }finally {
            JDBCUtil.close(stmt,conn);
        }
    }

事务回滚点

一次性去执行多条(10000)sql语句的时候。一出现异常,10000条全部回滚。
如果出现的问题,设置一个回滚点,回滚到那一个点,就行了,这就避免全部回滚

API

Savepoint sp = conn.setSavepoint() // 设置回滚点
conn.rollback(sp);//回滚到设置的点
conn.commit();//回滚后必须提交

案例实现

需求:向数据库发送10000条数据,每1000条是合理的

事务的特性ACID

原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位(最小的一个整体),事务中的操作要么都发生,要么都不发生。 
一组操作时一个整体。不能分割。

一致性(Consistency)
事务前后数据的完整性必须保持一致。
一致性和原子性相关。只有都成功或者,都失败(原子性) ,就可以保证事务的一致性。
事务的前后的内容一直。 
转账: a 1000 b 1000 a给b转100;
转账之前 a和b的总额 2000
转账之后 也要2000;

隔离性(Isolation)
事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。

多个事务是独立存在的。多个事务不能够相互干扰。
a –b---事务A
c-d---事务B
如果A失败了。不能够影响B

持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。 
a-100
b+100
提交
此时a永远少100
b永远的多了100

a – 100  a 900 
b+100   b 1100
commit;

a -100 a 800
b+100 b 1200
rollback : a 900  b 1100

rollback—异常。对上述没有任何影响了。

事务的隔离级别

如果不考虑事务的隔离性,将会产生以下问题:

由数据事务的并发造成的问题。

1、脏读,---最严重的事情
2、不可重复读
3、幻读(虚读)

脏读

一个事务读取了另外一个事务没有的提交的数据。非常严重。尽可能去避免掉脏读

不可重复读

一个事务读取另外一个提交过的数据。造成另外一个事务,多次读取的【内容】不一致,数据的内容的改变。 update

幻读(虚读)

一个事务读取另外一个事务已经提交的数据。但是这里面强调的数据数目的改变。insert,delete。

1、开始统计 100
用户下单 提交
2、查询 101

虚读和不可重复读

不可重复读: 同一条记录 内容的改变 --update

虚读: 条目数的改变---insert delete

数据库的事务隔离级别

数据库共定义了四种隔离级别:
Serializable:可避免脏读、不可重复读、虚读情况的发生。    (可串行化,一个事务一个事务运行)
Repeatable read:可避免脏读、不可重复读情况的发生。      (可重复读)【不可以避免虚读】
Read committed:可避免脏读情况发生。                     (读已提交)【避免不了虚读以及不可重复读】
Read uncommitted:最低级别,以上情况均无法保证。         (读未提交)
设置事务的隔离级别
set session transaction isolation level 设置事务隔离级别    两个人
select @@tx_isolation	查询当前事务隔离级别

评论需要登录。生产环境使用 GitHub 登录,本地可前往 登录页 使用开发登录。

还没有评论,来抢沙发。