事务的特性(ACID)

基本概念:
事务使指一组最小逻辑操作单元,里面有多个操作组成。组成事务的每一部分必须要同时提交成功,如果有一个操作失败,整个操作就回滚。

基本概念:
事务使指一组最小逻辑操作单元,里面有多个操作组成。组成事务的每一部分必须要同时提交成功,如果有一个操作失败,整个操作就回滚。


事务ACID特性

  • 原子性(Atomicity)
    原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

  • 一致性(Consistency)
    事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

  • 隔离性(Isolation)
    事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

  • 持久性(Durability)
    持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响


默认情况下,Connection 对象处于自动提交模式下,这意味着它在执行每个语句后都会自动提交更改。
如果禁用了自动提交模式,那么要提交更改就必须显式调用 commit 方法;否则无法保存数据库更改。

实例:

public class JDBCDemo2 {
    public static void main(String[] args) {
        //转账 张三要给李四转1000块钱
        //张三账户减去1000
        //李四账户增加 1000

        //第二次转转账 500
        Connection conn =null;
        PreparedStatement s1=null;
        PreparedStatement s2=null;
        PreparedStatement s3 = null;
        PreparedStatement s4 = null;
        Savepoint savepoint=null;
        try {
            //第一次转账
           conn = JDBCUtils.getConnection();
            conn.setAutoCommit(false);//禁止自动提交,将所有的SQL语句聚集到一个事务当中,手动提交或者回滚
            String sql1="update bank set money=money-1000 where username='张三'";
            String sql2 = "update bank set money=money+1000 where username='李四'";
             s1 = conn.prepareStatement(sql1);
             s2 = conn.prepareStatement(sql2);
             s1.executeUpdate();
              s2.executeUpdate();

              //第二次转账
             savepoint = conn.setSavepoint(); //设置一个回滚点

            String sql3 = "update bank set money=money-500 where username='张三'";
            String sql4 = "update bank set money=money+500 where username='李四'";
            s3 = conn.prepareStatement(sql3);
            s4 = conn.prepareStatement(sql4);
            s3.executeUpdate();
            System.out.println(1/0);
            s4.executeUpdate();

        } catch (Exception e) {
            e.printStackTrace();
            try {
               // conn.rollback();//一旦遇到异常,回滚到事务最初始的状态
                conn.rollback(savepoint); //会滚到,我设置的回滚点的位置
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                conn.commit();//手动提交事务
                //释放资源
                JDBCUtils.close(conn, s1);
                s2.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

隔离性:

  • 不考虑隔离性会出现的读问题★★
    1.脏读:在一个事务中读取到另一个事务没有提交的数据
    2.不可重复读:在一个事务中,两次查询的结果不一致(针对的update操作) 不可重复读,是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。
    3.虚读(幻读):在一个事务中,两次查询的结果不一致(针对的insert操作) 无法演示出来,MySQL已经默认避免了

  • MySQL 有四种隔离级别
    1.read uncommitted 读未提交 上面的三个问题都会出现
    2.read committed 读已提交 可以避免脏读的发生 Oracle 默认界别
    3.repeatable read 可重复读 可以避免脏读和不可重复读的发生 MySQL 默认级别(需要重新开启事务后才能看到结果)
    4.serializable 串行化 可以避免所有的问题

  • 演示脏读的发生:
    1.将数据库的隔离级别设置成 读未提交
    set session transaction isolation level read uncommitted;
    查看数据库的隔离级别
    select @@tx_isolation;
    2.打开两个窗口进行演示:给两个窗口设置好同的隔离级别
    3.开启事务 start transaction;
    4.修改数据:update bank set money=1500 where username=‘lisi’;
    5.让另一个窗口开启事务 查询数据 他查到了 就是脏读

  • 避免脏读的发生
    1.将隔离级别设置成 读已提交
    set session transaction isolation level read committed;
    2.避免不可重复读的发生 经隔离级别设置成 可重复读
    set session transaction isolation level repeatable read;
    3.演示串行化 (锁表的操作)可以避免所有的问题(我这边的事务不提交,那边的事务无法执行)
    set session transaction isolation level serializable;

  • 四种隔离级别的效率
    read uncommitted>read committed>repeatable read>serializable

  • 四种隔离级别的安全性
    read uncommitted<read committed<repeatable read<serializable

  • 开发中绝对不允许脏读发生
    mysql中默认级别:repeatable read
    oracle中默认级别:read committed

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值