day13_Mysql事务与数据库连接池学习笔记
一、Mysql的事务
事务:
事务指 逻辑上的一组操作,组成这组操作的各个单元,要么 全部成功,要么全部不成功(数据回滚) 。
例如:A给B转帐,对应于如下两条sql语句 :
- update account set money=money-100 where name='a';
- update account set money=money+100 where name='b';
1、Mysql中的事务
- a、mysql引擎是支持事务的。
- b、mysql语句默认是 自动提交事务 。每条语句都处在 单独的事务 中。
- c、手动控制事务(命令行):
开启事务 :start transaction; 或者 begin;
提交事务 :commit;
回滚事务 :rollback;
2、JDBC如何控制事务?
3、事务的特性(ACID)(面试题)
原子性(Atomicity):指事务是一个不可分割的工作单位 ,事务中的操作要么都发生,要么都不发生。多条语句变成一个不可分割的整体 。
一致性(Consistency) :事务必须使数据库从一个一致性状态变换到另外一个一致性状态。转账前和转账后的总金额不变。
隔离性(Isolation) :事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离 。(多线程)
持久性(Durability):指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
4、事务的隔离级别
赃读 :指一个事务读取了另一个事务未提交的数据。 读到的是假的数据
。
不可重复读 :在一个事务内读取表中的某一行数据,多次读取的结果不同。一个事务读取到了另一个事务提交后的数据。(update) 每次读到的结果不一样
。
虚读(幻读) :是指在一个事务内读取到了别的事务插入的数据,导致前后读取的结果不一致。(insert) 读到的数据变多了 。
数据库通过设置事务的隔离级别
防止以上情况的发生:
1、READ UNCOMMITTED: 赃读、不可重复读、虚读都有可能发生。 read uncommitted
2、READ COMMITTED: 避免赃读。不可重复读、虚读都有可能发生。(oracle默认的) read committed
4、REPEATABLE READ: 避免赃读、不可重复读。虚读有可能发生。(mysql默认的) repeatable read
8、SERIALIZABLE: 避免赃读、不可重复读、虚读。 serializable
级别越高,性能越低,数据越安全。实际开发是以级别2、4为主,其余的用程序控制。
mysql中:
查看当前的事务隔离级别:SELECT @@TX_ISOLATION;
更改当前的事务隔离级别:SET TRANSACTION ISOLATION LEVEL 四个级别之一。
特别注意:设置隔离级别必须在开启事务之前。
5、JDBC控制事务的隔离级别
Connection接口:
JDBC代码中设置隔离级别:必须在开启事务之前。
注意:mysql的默认级别,若是操作mysql数据库,可以不用设置,默认设置就是这个。
二、数据库连接池
1、连接池原理(面试)
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;通过释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。
这项技术能明显提高对数据库操作的性能。
目的:解决建立数据库连接耗费资源和时间很多的问题,提高性能。
图1
图2
2、编写标准的数据源
自定义的数据库连接池要实现javax.sql.DataSource接口,一般都叫数据源。
实现DataSource接口,并实现连接池功能的步骤:
1、在MyDataSource构造函数中批量创建与数据库的连接,并把创建的连接加入LinkedList对象中。
2、实现getConnection方法,让getConnection方法每次调用时,从LinkedList中取一个Connection返回给用户。
3、当用户使用完Connection,调用Connection.close()方法时,Collection对象应保证将自己返回到LinkedList中,而不要把conn还给数据库。
Collection保证将自己返回到LinkedList中是此处编程的难点。
3、编写数据源时遇到的问题及解决办法
a、装饰设计模式:使用频率很高
目的:改写已存在的类的某个方法或某些方法,装饰设计模式(包装设计模式)
口诀:
1、编写一个类,实现与被包装类相同的接口。(具备相同的行为)
2、定义一个被包装类类型的变量。
3、定义构造方法,把被包装类的对象注入,给被包装类变量赋值。
4、对于不需要改写的方法,调用原有的方法。
5、对于需要改写的方法,写自己的代码。
// 该类本身就是一个装饰类,对原类的具体装饰饰在该类中实现。(但是需要写很多多余的代码)
b、默认适配器模式:是装饰设计模式的一个变体
包装适配器类:
包装适配器实现类:
4、常用的数据源配置
因为日后都使用数据源,所以一定要配置一下。
4.1、DBCP(数据源开源框架)
DBCP:Apache推出的 DataBase Connection Pool 数据连接池(数据源)
使用步骤:
添加jar包:commons-dbcp-1.4.jar 和 commons-pool-1.5.6.jar 和 mysql-connector-java-5.0.8-bin.jar
添加属性资源文件(等待时间,最大连接数等配置信息)
编写数据源操作的工具类
数据源操作的工具类:
测试类:
4.2、C3P0
使用步骤:
1、添加jar包
这次我们使用的是Java Project项目,在该项目下新建lib文件夹,添加jar包:c3p0-0.9.1.2.jar,再添加至构建路径。
2、编写配置文件
c3p0-config.xml,放在classpath中,或classes目录中
3、编写操作数据源的工具类
4、编写测试类
注意:测试类类名TsetCRUD、TestDao、TestJDBC,名字含义都一样。
5、用JavaWeb服务器管理数据源(连接池):比如用Tomcat,此时不需要导入jar包
开发JavaWeb应用,必须使用一个JavaWeb服务器,JavaWeb服务器都内置数据源。
Tomcat:(DBCP)
数据源只需要配置服务器即可。
配置数据源的步骤:
1、拷贝数据库连接的jar包mysql-connector-java-5.0.8-bin.jar到tomcat的lib目录下。
2、配置数据源XML文件:
a)如果把配置信息写在tomcat下的conf目录的context.xml中,可以配置多个不同的数据源,那么所有应用都能使用此数据源。
b)如果是在当前应用的META-INF中创建context.xml,编写数据源,那么只有当前应用可以使用此数据源。
演示b)
context.xml文件
3、如何使用连接池呢?如下:
在xxx.jsp下加入:
<% ...... %>
JNDI:java nameing directory interface
有多个<Resource/>
,就有多个name,多个name就变成了JNDI。
JNDI容器就是一个Map。
三、自定义JDBC框架(练技术)
1、数据库元信息的获取(很简单、很无聊、很重要)
- a、元信息:(Meta Data)指数据库或表等的定义信息。
2、自定义JDBC框架
- 反射:
- 策略设计模式:
【转载文章务必保留出处和署名,谢谢!】