事物_软件分层

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyande123/article/details/78509383

事务

事务是:在数据库指业务处理的”一个业务“对应数据库中的多个步骤的操作。例如银行转账。

面对的问题:程序接受请求后,会至少发送两条SQL语句,两条语句之间会有时间的间隔,如果间隔时间期间Mysql服务器发生意外,导致第二条SQL无法执行,导致整个业务的最终数据错误。所以,所有的数据库软件,都必须具有一种能力,可接收一系列的“SQL”语句,将这些SQL语句看做是一个“整体”执行后,要么全部成功,要么全部失败这种能力就是:事务处理

数据库中的事务操作

  • JDBC操作数据库的事务操作
  • DBUtils中的数据库的事务操作

数据库中的事务处理:1、手动提交、2、自动提交情况下开启一个临时事务处理

  1. mysql中默认的事务处理方式,自动提交–将每条SQL语句看做是一个独立的事务,执行后会立即更改数据库,与其他的SQL语句没有关联。不能满足我们对事务的处理需求。
  2. 怎么查看当前mysql的事务处理方式:show variables like ‘autocommit’;
  3. mysql中的事务处理的两种

    1. 关闭自动提交:set autocommit =off;(开启是 ON)
    2. 执行SQL语句
    3. 提交/回滚:commit;//提交 | rollback;回滚
    4. 【注意】当提交或者回滚后,之前的SQL语句被全部处理。要么全部更改打数据库,要么全部取消。之后新的SQL语句,就是新的事务。
    5. 【注意】 事务提交后不能被回滚,回滚之后也不能被提交了。
  4. 在“自动提交”状态下,开启临时一个“手动事务”

    1. 开启临时事务:start tansaction;
    2. 执行SQL语句
    3. 提交或回滚临时事务:commit; | rollback;
    4. 【注意】只要提交事务,这个事务就结束了,立即恢复到之前的自动事务状态
    5. 【注意】事务对于mysql是“回话级别的”每个回话都可以单独设置事务的处理,会不影响,互相隔离;
    6. 【注意】在一个“会话中”的查询结果是可以查询到之前修改的结果不论是否提交/回顾;但在另一个回话中,查询时查询不出来的。

代码

JDBC中的事务处理

public class Demo {

public static void main(String[] args)throws Exception {
    String url="jdbc:mysql://localhost:3306/db_demo";
    String user="root";
    String pwd="123456";
    //注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    //获取连接
    Connection con = DriverManager.getConnection(url,user,pwd);
    //关闭数据库自动提交
    con.setAutoCommit(false);
    //获取SQL执行器
    Statement stmt = con.createStatement();
    try{

        String sql1="update account set balance=balance-1000 where userName='zhangsan'";
        int row1 = stmt.executeUpdate(sql1);
        String sql2="update account set balance=balance+1000 where userName='lisi'";
        int row2 = stmt.executeUpdate(sql2);
        System.out.println(row1+" ==="+row2);
        if(row1!=1||row2!=1){
            con.rollback();
            System.out.println("回滚了");
        }else{
            con.commit();            
        }
    }catch(Exception e){
        con.rollback();
        System.out.println("异常了  回滚了");
        e.printStackTrace();
    }
    con.close();
}
}

DBUtils中的事务处理

public class Demo {

public static void main(String[] args) throws Exception{
    //创建QueryRuanner对象是Dbutils工具类里的类 查询、增删改等操作
    QueryRunner qr=new QueryRunner();
    //创建连接池状态
    ComboPooledDataSource ds= new ComboPooledDataSource();
    Connection con = ds.getConnection();
    con.setAutoCommit(false);
    try{
        String sql1="update account set balance=balance-1000 where userName='zhangsan'";
        String sql2="update account set balance=balance+1000 where userName='lisi'";
        int row1 = qr.update(con, sql1);
        int row2 = qr.update(con, sql2);
        if(row1!=1||row2!=1){
            con.rollback();
            System.out.println("出错了");
        }else{
            con.commit();
            System.out.println("成功了");
        }
    }catch(Exception e){
        con.rollback();
        System.out.println("异常了,回滚了");
    }
    con.setAutoCommit(true);
    con.close();

}
}

软件分层

1).视图层(view):负责接收数据、命令、展示数据;

2).控制层(controller):负责接收视图层的数据、命令,寻找相应的”业务层”进行处理(业务分发)

3).业务层:负责具体的业务逻辑实现

4).持久层(Dao):负责持久化数据的(访问数据库)

5).模型层(model):负责封装数据,在各层之间传递数据。

分层的好处:

1).将代码解耦,使各功能部分的代码之间的耦合度降到最低。不同功能的代码分到不同的类中存储,后期需要修改时,修改哪部分代码,就找哪层的类即可,其它类不用改。

有一句话:高内聚、低耦合
高内聚:功能相同、相近的代码放到同一个类中;
低耦合:各功能的代码之间降低耦合;

事务特性 ACID

  • 原子性
  • 一致性
  • 隔离性
  • 持久性

不考虑两个事务的隔离性会产生的问题

  • 脏读:一个事务读到了另一个事务未提交的数据.
  • 不可重复读:一个事务读到了另一个事务已经提交(update)的数据。引发另一个事务,在事务中的多次查询结果不一致。
  • 虚读/幻读:一个事务读到了另一个事务已经提交(insert)的数据。导致另一个事务,在事务中多次查询的结果不一致。

事务的隔离级别

1).read uncommitted:读未提交;最低级;基本上不隔离。可以读到脏数据。

2).read committed:读已提交;可以解决脏读,但不能解决”不可重复读”和”幻读”;

3).repeatable read: 可重复读。在MYSQL下可以解决:脏读、不可重复的、幻读;(MySQL的默认级别)

4).serializable :将两个事务完全隔离,一个事务未结束时,另一个事务必须等待;


查看当前数据库的隔离级别:
select @@tx_isolation;

设置会话的事务隔离级别:
set session transaction isolation level 上面的四个隔离级别之一;

安全和性能对比
安全性:serializable > repeatable read > read committed > read uncommitted

性能 : serializable < repeatable read < read committed < read uncommitted

常见数据库的默认隔离级别:

MySql:repeatable read(第三级)

Oracle:read committed(第二级)

ThreadLocal 类的工作原理

可以保存一个Connection对象,当Dao层需要的时候可以直接获取数据库连接对象。不需要每层在传递Connection对象,到Dao层。

猜你喜欢

转载自blog.csdn.net/huyande123/article/details/78509383