zoukankan      html  css  js  c++  java
  • jdbc(2)

    create table account (
    id int primary key auto_increment,
    name varchar(20),
    money double
    );
    insert into account values(null,'a',1000),(null,'b',1000);

    一、事务
    事务的概念:事务是指逻辑上的一组操作,这组操作要么同时完成要么同时不完成.

    事务的管理:默认情况下,数据库会自动管理事务,管理的方式是一条语句就独占一个事务.
    如果需要自己控制事务也可以通过如下命令开启/提交/回滚事务
    start transaction;
    commit;
    rollback;

    JDBC中管理事务:
    conn.setAutoCommit(false);
    conn.commit();
    conn.rollback();
    SavePoint sp = conn.setSavePoint();
    conn.rollback(sp);

    事务的四大特性:一个事务具有的最基本的特性,一个设计良好的数据库可以帮我们保证事务具有这四大特性(ACID)
    原子性:原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 
    一致性:如果事务执行之前数据库是一个完整性的状态,那么事务结束后,无论事务是否执行成功,数据库仍然是一个完整性状态.
    数据库的完整性状态:当一个数据库中的所有的数据都符合数据库中所定义的所有的约束,此时可以称数据库是一个完整性状态.
    隔离性:事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。
    持久性:持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。


    隔离性:
    将数据库设计成单线程的数据库,可以防止所有的线程安全问题,自然就保证了隔离性.但是如果数据库设计成这样,那么效率就会极其低下.

    数据库中的锁机制:
    共享锁:在非Serializable隔离级别做查询不加任何锁,而在Serializable隔离级别下做的查询加共享锁,
    共享锁的特点:共享锁和共享锁可以共存,但是共享锁和排他锁不能共存
    排他锁:在所有隔离级别下进行增删改的操作都会加排他锁,
    排他锁的特点:和任意其他锁都不能共存

    如果是两个线程并发修改,一定会互相捣乱,这时必须利用锁机制防止多个线程的并发修改
    如果两个线程并发查询,没有线程安全问题

    如果两个线程一个修改,一个查询......
    四大隔离级别:
    Read uncommitted -- 不防止任何隔离性问题,具有脏读/不可重复度/虚读(幻读)问题
    Read committed -- 可以防止脏读问题,但是不能防止不可重复度/虚读(幻读)问题
    Repeatable read -- 可以防止脏读/不可重复读问题,但是不能防止虚读(幻读)问题
    Serializable -- 数据库被设计为单线程数据库,可以防止上述所有问题

    从安全性上考虑: Serializable>Repeatable read>read committed>read uncommitted
    从效率上考虑: read uncommitted>read committed>Repeatable read>Serializable

    真正使用数据的时候,根据自己使用数据库的需求,综合分析对安全性和对效率的要求,选择一个隔离级别使数据库运行在这个隔离级别上.
    mysql 默认下就是Repeatable read隔离级别
    oracle 默认下就是read committed个隔离级别

    查询当前数据库的隔离级别:select @@tx_isolation;
    设置隔离级别:set [global/session] transaction isolation level xxxx;其中如果不写默认是session指的是修改当前客户端和数据库交互时的隔离级别,而如果使用golbal,则修改的是数据库的默认隔离级别


    脏读:一个事务读取到另一个事务未提交的数据
    a 1000
    b 1000

    ----------
    a:
    start transaction;
    update account set money=money-100 where name=a;
    update account set money=money+100 where name=b;
    ----------
    b:
    start transaction;
    select * from account;

    a : 900
    b : 1100
    ----------
    a:
    rollback;
    ----------
    b:
    start transaction;
    select* from account;
    a: 1000
    b: 1000



    不可重复读:在一个事务内读取表中的某一行数据,多次读取结果不同 --- 行级别的问题
    a: 1000 1000 1000
    b: 银行职员

    ---------
    b:start transaction;
    select 活期存款 from account where name='a'; ---- 活期存款:1000
    select 定期存款 from account where name='a'; ---- 定期存款:1000
    select 固定资产 from account where name='a'; ---- 固定资产:1000
    -------
    a:
    start transaction;
    update accounset set 活期=活期-1000 where name='a';
    commit;
    -------
    select 活期+定期+固定 from account where name='a'; --- 总资产:2000
    commit;
    ----------

    虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致 --- 表级别的问题
    a: 1000
    b: 1000
    d: 银行业务人员

    -----------
    d:
    start transaction;
    select sum(money) from account; --- 2000 元
    select count(name) from account; --- 2 个

    ------
    c:
    start transaction;
    insert into account values(c,4000);
    commit;
    ------

    select sum(money)/count(name) from account; --- 平均:2000元/个
    commit;
    ------------


    更新丢失问题:
    两个线程基于同一个查询结果进行修改,后修改的人会将先修改人的修改覆盖掉.

    悲观锁:悲观锁悲观的认为每一次操作都会造成更新丢失问题,在每次查询时就加上排他锁

    乐观锁:乐观锁会乐观的认为每次查询都不会造成更新丢失.利用一个版本字段进行控制


    查询非常多,修改非常少,使用乐观锁
    修改非常多,查询非常少,使用悲观锁


    =================================================================================
    二、数据库连接池

    手写连接池:
    改造conn的close方法

    继承
    装饰
    !动态代理

    开源数据源:
    DBCP:
    方式1:

    BasicDataSource source = new BasicDataSource();
    source.setDriverClassName("com.mysql.jdbc.Driver");
    source.setUrl("jdbc:mysql:///day11");
    source.setUsername("root");
    source.setPassword("root");

    方式2:

    Properties prop = new Properties();
    prop.load(new FileReader("dbcp.properties"));
    BasicDataSourceFactory factory = new BasicDataSourceFactory();
    DataSource source = factory.createDataSource(prop);

    配置文件中:

    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql:///day11
    username=root
    password=root



    #<!-- 初始化连接 -->
    initialSize=10

    #最大连接数量
    maxActive=50

    #<!-- 最大空闲连接 -->
    maxIdle=20

    #<!-- 最小空闲连接 -->
    minIdle=5

    #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
    maxWait=60000

    C3P0数据源:
    方式1:

    ComboPooledDataSource source = new ComboPooledDataSource();
    source.setDriverClass("com.mysql.jdbc.Driver");
    source.setJdbcUrl("jdbc:mysql:///day11");
    source.setUser("root");
    source.setPassword("root");

    方式2:

    ComboPooledDataSource source = new ComboPooledDataSource();


    在类加载目录下名称为c3p0-config.xml的配置文件中配置:

    <c3p0-config>
    <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql:///day11</property>
    <property name="user">root</property>
    <property name="password">root</property>
    </default-config>
    </c3p0-config>


    tomcat内置的数据源(DBCP):
    ~1.如何为tomcat配置数据源
    ~tomcat/conf/context.xml文件中配置<Context>配置在这个位置的信息将会被所有的web应用所共享
    ~tomcat/conf/[engin]/[Host]/context.xml文件中可以配置<Context>标签,这里配置的信息将会被这台虚拟主机中的所有web应用所共享

    ~tomcat/conf/server.xml文件中的<Host>标签中配置<Context>标签,这是web应用的第一种配置方式,在这个标签中配置的信息将只对当前web应用起作用
    ~tomcat/conf/[engin]/[Host]/自己创建一个.xml文件,在这个文件中使用<Context>标签配置一个web应用,这是web应用第二种配置方式,在这个<Context>标签中配置的信息将只会对当前web应用起作用
    ~web应用还有第三种配置方式:将web应用直接放置到虚拟主机管理的目录.此时可以在web应用的META-INF文件夹下创建一个context.xml文件,在其中可以写<Context>标签进行配置,这种配置信息将只会对当前web应用起作用

    <Resource name="mySource"
    auth="Container"
    type="javax.sql.DataSource"
    username="root"
    password="root"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql:///day11"
    maxActive="8"
    maxIdle="4"/>

    ~2.如果在程序中获取这个数据源
    想要访问jndi就必须在Servlet中才能执行下列代码:

    Context initCtx = new InitialContext();
    Context jndi = (Context) initCtx.lookup("java:comp/env");
    DataSource source = jndi.lookUp("mySource");


    天行健,君子以自强不息
  • 相关阅读:
    新浪微盘又是一个给力的产品啊,
    InfoQ: 百度数据库架构演变与设计
    列式数据库——Sybase IQ
    MapR初体验 淘宝共享数据平台 tbdata.org
    IBM正式发布新一代zEnterprise大型机(组图) 大型机,IBM,BladeCenter,美国,纽约 TechWeb News
    1TB is equal to the number of how many GB? 1PB equal to is equal to the number of TB? 1EB PB? | PCfault.com
    Cassandra vs HBase | WhyNosql
    The Hadoop Community Effect
    雅虎剥离开源软件平台 Hadoop ,与风投新建 Hortonworks 公司 品味雅虎
    RowOriented Database 、ColumnOriented Database 、KeyValue Store Database 、DocumentOriented Database
  • 原文地址:https://www.cnblogs.com/god-y-l/p/6793956.html
Copyright © 2011-2022 走看看