• 事务应用-Dao的综合应用


    一、事务应用

    1、事务定义

    ​ 用于完成一件事件的独立单元 例如:我们在数据库操作的时候,对数据库的一次更新可以认为是一个事务,业务中银行转账也可以是一个事务(余额的变更)

    2、事务的四个特性

    ​ a、原子性: 一个事务在执行过程中, 要么全部执行,要么全部不执行,不可能停滞了中途,及时中途失败了,也会回滚到初始状态, 事务是一个不可分割的独立单元

    ​ b、一致性: 事务体现在数据库操作中,在事务开始前和结束后,它们的完整性约束没有被破坏,保持前后一致

    ​ c、隔离性: 同一时间 ,只允许一个事务处理同一条数据 , 事务和事务相互独立并隔离, 多个事务之间处理同一条数据 必须考虑事务的隔离级别问题

    ​ d、持久性: 事务可以提交(commit),也可以回滚(rollbck) ,事务一旦提交将永久生效,事务的回滚可以返回到修改之前的状态。

    3、MySql中事务演示

    ​ 默认情况下,MySql的事务是自动提交 ,

    ​ 查询事务的提交方式

    show variables  like 'autocommit';
    

    ​ ON:自动 OFF:关闭

    更改事务的提交方式

    set @@autocommit =0 ;
    

    ​ 注意 以上只能更改当前窗口的事务提交方式,如果需要全局更改 ,需要在my.ini下 添加如下

    set @@autocommit =0 ; 然后重启mysql服务

    -- 手动提交事务 
    select * from t_user;
    update t_user set money =400 where userid =1;
    -- 对于没有提交的记录 ,会锁行(行级锁)
    commit;
    rollback;
    
    

    事务的并发产生的问题

    1、 脏读: 事务A 读取了 事务B未提交的数据 ,假如事务B 对数据更新后,事务A读取了一次,事务B对数据回滚了, 事务A再次读取一次,事务A发现 第一次读的数据是脏数据。

    2、不可重复读: 事务A多次读取同一条记录,事务B在期间进行提交了,到时事务A读取的数据前后不一致,这是属于 不可重复读 。

    3、幻读: 对于新增记录而言, 事务A第一次读取 与第二个读取的表数据总行数 不一致 ,不一致原因是 在期间事务B可能添加了记录 ,导致事务A出现 幻觉多了一条记录。

    MySql的默认隔离级别: 可重复读取

    select @@transaction_isolation

    REPEATABLE-READ

    修改MySql的隔离级别:

    	set session transaction isolation level read committed ;
    
    
    隔离级别 脏读 不可重复读 幻读
    读未提交数据(read uncommitted)
    读已提交数据(read committed)
    可重复读(repeatable-read )
    序列化(serializable)

    4、JDBC中 事务的手动提交

    默认情况下 JDBC的事务是自动提交的, 由于在特定的业务场景下 一个事务需要执行多个sql语句 ,例如转账业务 ,账户A给账户B转账100元, 账户A的余额需要减少100 , 而账户B的余额要增加100 (2个sql)

      public static void main(String[] args) {
              // 账户A  给账户B 转账
            MyUser fromUser = new MyUser();
            fromUser.setUserid(1);
    
            MyUser toUser = new MyUser();
            toUser.setUserid(2);
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入转账的金额");
            double money  = sc.nextDouble();
    
            // 获取连接对象
           Connection conn  = null;
            PreparedStatement ps = null;
           // 设置该连接为 手动提交事务
            try {
                conn =  DBUtil.getConn();
                conn.setAutoCommit(false);
                String sql1 = "update t_user set money = money-"+money +" where userid = ?";
                ps = conn.prepareStatement(sql1);
                // 设置参数
                ps.setInt(1,fromUser.getUserid());
                // 执行
               int count1=   ps.executeUpdate();
                System.out.println("count1----"+count1);
    
               //模拟突然断电
                System.out.println(10/0);
    
               //  另一个账户的钱 增多
                sql1 =  "update t_user set money = ifnull(money,0)+"+money +" where userid = ?";
                ps = conn.prepareStatement(sql1);
                ps.setInt(1,toUser.getUserid());
                //执行
                int count2 = ps.executeUpdate();
                System.out.println("count2----"+count2);
    
                // 提交事务
                conn.commit();;
                System.out.println("转账成功");
            } catch (Exception e) {
                e.printStackTrace();
                // 回滚
                try {
                    conn.rollback();
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
                System.out.println("转账失败");
            } finally {
                //关闭连接
                DBUtil.closeAll(conn , ps , null);
            }
        }
    

    二、DAO的综合应用

    ​ 创建图书表和 用户表 ,完成后台图书管理系统。

    1、建立独立项目: 项目包括 dao 、entity、 util包

    ​ dao中不同的表提供不同的接口 和 实现类

    ​ entity中提供对应表的实体类

    ​ util包装 提供 DBUtil类

    写一个控制台程序,调用 dao的实现类 (BookDaoImpl、UserDaoImpl)

    完成功能:

    ​ 1、用户登录,用户注册(注册时验证用户是否存在)

    ​ 2、图书管理: 添加图书,删除图书,修改图书,查询所有图书,根据ID查询图书。

    b_user : 用户id 用户名 密码 状态

    book :图书id ,图书名,图书作者,图书价格,图书发布时间 ,图书所属的userid (外键)

    项目分层:

    项目名

    ​ -|src

    ​ -| com.j2008

    ​ -|util : DBUtil.java

    ​ -| entity: XXX.java ...

    ​ -|dao: XXXDao.java

    ​ XXXDaoImpl.java

    ​ -| client : 测试类 控制台输入

  • 相关阅读:
    Linux 查看CPU个数和磁盘个数
    springboot 文件上传大小配置
    Netty(一):初识Netty
    Java 8里 Stream和parallelStream的区别
    Logstash filter 的使用
    logstash过滤器插件filter详解及实例
    Linux下如何不停止服务,清空nohup.out文件
    logstash收集Nginx日志,转换为JSON格式
    Logstash add_field 参数应用
    Logstash处理json格式日志文件的三种方法
  • 原文地址:https://www.cnblogs.com/z5452830/p/14053517.html
Copyright © 2020-2023  润新知