zoukankan      html  css  js  c++  java
  • Java实战之04JavaWeb-05事务和连接池

    一、事务部分

    1.事务的简介

    做一件事情,这个一件事情中有多个组成单元,这个多个组成单元要不同时成功,要不同时失败。A账户转给B账户钱,将A账户转出钱的操作与B账户转入钱的操作绑定到一个事务中,要不这两个动作同时成功,代表这次转账成功,要不就两个动作同时失败,代表这次转账失败。

    2.mysql的事务控制

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

    手动开启事务:start transaction

    当手动开启事务后,数据库默认的事务的自动提交暂时失效

    提交事务:commit

    提交事务到开启事务之间的所有的sql语句都生效

    回滚事务:rollback

    从回滚事务到开启事务之间的所有的sql操作都无效

    3.jdbc的API的事务控制

    通过Connection对象可以控制事务

    jdbc中想控制事务其实是控制jdbc的更新数据库的API方法---executeUpdate

    开启事务:connection.setAutoCommit(false);

    提交事务:connection.commit();

    回滚事务:connection.rollback();

    4.事务的四大特性ACID

    原子性:数据库的操作的最小的单位就是事务

    一致性:一个事务中的多个操作的结果数据是一致的,同时成功和同时失败

    隔离性:多个事务之间的操作互不影响

    持久性:当一个事务提交后,更新操作才持久化到磁盘上

    在不考虑隔离性的前提下会产生哪些影响?

    模拟两个事务A事务  B事务

    脏读:B事务读到了A事务尚未提交的事务

    不可重复读:A事务中两次读取的数据的内容不一致

    虚读/幻读:A事务中两次读取的数据的数量不一致

    5.事务的隔离级别

    通过设置数据库的隔离级别 解决上述的问题:

    read uncommitted:读取尚未提交的事务,什么都不能解决

    read committed:读取已经提交的内容,可以解决脏读

    repeatable read:重复读,可以解决脏读和不可重复读

    serializable:串行化,可以解决所有

    数据库默认的隔离级别

    mysql的默认隔离级别:repeatable read

    oracle的默认的隔离级别:read committed

    查询数据库的隔离级别:select @@tx_isolation

    手动的修改数据库默认的隔离级别:

    set session transaction isolation level 设置事务隔离级别

    模拟脏读步骤:

    1)开启两个客户端 分别进入数据库

    2)设置两个客户端数据库隔离级别为read uncommitted

    3)两个客户端分别开启事务

    4)A客户端修改数据但是尚未提交

    5)B客户端查询数据 发现数据已经修改

    6)A客户端回滚

    隔离级别性能问题:serializable<repeatable read<read committed<read uncommitted

    隔离级别安全问题:serializable>repeatable read>read committed>read uncommitted

    注意:事务控制必须在service层

    ThreadLocal:代表是专门存放当前线程的数据的map

    获取当前线程的数据:get();

    设置当前线程上绑定的数据:set(value)

    删除当前线程上绑定的数据:remove()

    二、连接池部分

    1.连接池的简介

    (1)什么是连接池

    存放数据库连接资源(Connection)的池子

    (2)为什么需要连接池

    1)节约连接资源 提高程序的性能

    2)防止数据库服务器连接资源溢出

    (3)连接池内部的原理

    1)连接池一创建就初始化一些Connection资源

    2)当使用Connection时不是创建而是从池子中获取一个资源

    3)当资源使用完毕 不是将该资源销毁 而是将资源在归还给池子

    (4)自定义连接池

     1 public class MyDataSource {
     2     //1、创建一个池子
     3     private static LinkedList<Connection> datasource = new LinkedList<Connection>();
     4     //2、在创建DataSource时 就为池子初始化一些连接资源
     5     public MyDataSource(int count){
     6         for(int i=0;i<count;i++){
     7             try {
     8                 //conn 是mysql驱动包提供的对象
     9                 Connection conn = JDBCUtils.getConnection();
    10                 //怎样对一个对象中的方法进行加强
    11                 //BufferedReader reader = new BufferedReader(new FileReader(""));
    12                 ConnectionWrapper wrapper = new ConnectionWrapper(conn);
    13                 //在将connnection资源放置到池子中之前 对conn进行一些加强(主要加强是close方法)
    14                 datasource.add(wrapper);
    15             } catch (Exception e) {
    16                 e.printStackTrace();
    17             }
    18         }
    19     }
    20     //获取connection的方法
    21     public static Connection getConnection(){
    22         return datasource.removeFirst();
    23     }
    24     //将使用完毕的资源放回池子中
    25     public static void giveBack(Connection conn){
    26         System.out.println("归还前的数量:"+datasource.size());
    27         datasource.addLast(conn);
    28         System.out.println("归还后的数量:"+datasource.size());
    29     }
    30     public static void main(String[] args) throws SQLException {
    31         MyDataSource dataSource = new MyDataSource(10);
    32         Connection conn = dataSource.getConnection();
    33         System.out.println(conn);
    34         //调用PreparedStatement对象
    35         PreparedStatement pstmt = conn.prepareStatement("select * from account");
    36         System.out.println(pstmt);
    37         ///dataSource.giveBack(conn);
    38         //问题:想要做的是当conn在调用close方法时 不是销毁 而是将conn放回池子中
    39         conn.close();
    40     }
    41 }

    装饰者模式:

    1)加强的类与被加强的类必须实现同一个接口

    2)要将被加强的类作为构造器的参数传入

    3)要加强的方法重写逻辑,不需要加强的方法调用被加强的

    2.常用的开源的连接池技术

    DBCP:Apache基金会的开源的连接池技术 Commons项目中子项目

    C3P0:开源的连接池技术

    (1)DBCP连接池技术

    下载jar包

    导入jar包

     1 public class DBCPDemo {
     2     @Test
     3     public void test1() throws SQLException{
     4         //1、获得一个连接池
     5         BasicDataSource dataSource = new BasicDataSource();
     6         //设置数据库的信息
     7         dataSource.setDriverClassName("com.mysql.jdbc.Driver");
     8         dataSource.setUrl("jdbc:mysql:///database");
     9         dataSource.setUsername("root");
    10         dataSource.setPassword("root");
    11         //2、获得一个连接资源
    12         Connection conn = dataSource.getConnection();
    13         System.out.println(conn);
    14         //3、将资源归还
    15         conn.close();
    16     }
    17     @Test
    18     public void test2() throws Exception{
    19         InputStream in = DBCPDemo.class.getClassLoader().getResourceAsStream("dbcp.properties");
    20         Properties pro = new Properties();
    21         pro.load(in);
    22         DataSource dataSource = BasicDataSourceFactory.createDataSource(pro);
    23         Connection conn = dataSource.getConnection();
    24         System.out.println(conn);
    25         conn.close();
    26     }
    27 }

    (2)C3P0连接池

    下载jar包

    导入jar包

     1 public class C3P0Demo {
     2     @Test
     3     public void test1() throws Exception{
     4         //创建连接池
     5         ComboPooledDataSource dataSource = new ComboPooledDataSource();
     6         //设置四个基本参数
     7         dataSource.setDriverClass("com.mysql.jdbc.Driver");
     8         dataSource.setJdbcUrl("jdbc:mysql:///database");
     9         dataSource.setUser("root");
    10         dataSource.setPassword("root");
    11         //获取连接
    12         Connection conn = dataSource.getConnection();
    13         System.out.println(conn);
    14         conn.close();
    15     }
    16     @Test
    17     public void test2() throws SQLException{
    18         //创建连接池
    19         //ComboPooledDataSource dataSource = new ComboPooledDataSource("haohao");
    20         ComboPooledDataSource dataSource = new ComboPooledDataSource();
    21         Connection conn = dataSource.getConnection();
    22         System.out.println(conn);
    23         conn.close();
    24     }
    25 }
  • 相关阅读:
    20191024-6 Alpha发布用户使用报告
    【第三章】MySQL数据库的字段约束:数据完整性、主键、外键、非空、默认值、自增、唯一性
    【第六章】MySQL日志文件管理
    【第四章】MySQL数据库的基本操作:数据库、表的创建插入查看
    【第一章】MySQL数据概述
    【Linux运维】LNMP环境配置
    【Linux 运维】linux系统修改主机名
    【Linux 运维】linux系统查看版本信息
    【Linux 运维】Centos7初始化网络配置
    50、树中两个节点的公共祖先
  • 原文地址:https://www.cnblogs.com/minihouseCoder/p/5625415.html
Copyright © 2011-2022 走看看