day16_transaction
数据库事务的介绍&操作数据库事务的命令
指的是为了一个业务功能,展开一组操作,这组操作要么全部成功,要么全部不成功.
例如: 经典的银行转账, aaa---- bbb 转账 100块钱
两条sql语句, 首先将aaa的帐号 减去 100 块钱, 然后将bbb的帐号 加100块钱.
在mysql中,默认的情况下 一条sql 语句就是处于一次事务中, 如果你要自己去手动的管理事务, 那么你可以通过
如下的命令来操作.
Start transaction ----开启事务
...
Rollback ---- 回滚事务
Commit---- 提交事务
jdbc程序管理事务快速入门
jdbc管理事务的注意点
管理事务设置回滚点
数据库的事务特性&不考虑隔离性会引发的问题_四种隔离级别
ACID
在数据库的事务特性中, 最重要的是隔离性,如果 多个事务共同同时操作 同一个表中数据时, 不考虑 隔离性,
那么就会引发灰常严重的问题, 主要会有以下的三类问题:
第一类: 脏读(dirty read ), 一个事务在操作的时候,读到了其他的事务未提交的数据, 这叫做脏读,也是最严重的
问题.
第二类: 不可重复读(unreatable read), 一个事务在操作的时候,读到的其他的事务已经提交的数据 , 主要指
通过update 语句对数据库中现有的数据进行了更新操作
第三类: 虚读,幻读(phantom read), 一个事务在操作的时候,读到的其他的事务已经提交的数据, 主要值 使用
Insert 语句 插入了新的记录
针对以上三类问题,数据库 提供了4 种 隔离级别, 用于解决以上三类问题.
第一种: read uncommitted (读未 提交), 会产生 脏读, 不可重复读, 虚读的发生是有概率的
第二种: read committed(读已提交), 不会产生脏读, 但是会引发不可重复读. 虚读的发生是有概率的
第三种: repeatable read (可以重复读), 不会发生脏读, 不可重复读, 虚读发生是有概率的
第四种: serializable (串行化), 不会发生以上的三类问题.
设置事务的隔离性的命令以及查看窗口的隔离级别
通过如下的命令 可以去更改 隔离级别 :
set session transaction isolation level 隔离级别值---- 设置当前的隔离级别了
select @@tx_isolation ----查询当前的隔离级别
这些问题, 都是在 事务操作过程中 才会出现的. 所以 肯定会去使用
Start transaction ----开启事务
Rollback----- 回滚事务
Commit ---提交事务
事务隔离级别的窗口演示
对于 以上四种隔离级别,串行化解决了所有的问题, 但是效率是最低的, 实际开发中,最常用的是
第二种以及第三种隔离级别.
Mysql: 默认的隔离级别是 repeatable read
Oracle: 默认的隔离级别是 read committed
实际开发过程中,是通过 java代码去实现 事务的管理控制,设置隔离级别
- 如何去设置隔离级别呢?
找到Connection类
有如下的api 去设置 隔离级别
针对 数据库中的隔离级别,sun公司在定义jdbc的接口规范的时候,
就设置了4 个常量, 用于 设置具体的隔离级别 .
自定义连接池的实现
连接池的核心思想是:一次性的批量的弄出多个连接对象放到连接池中,当需要 操作数据库的时候,就
从连接池中取出一个 链接 使用,当用完了连接 之后, 再次将连接放回到池子中去,这样
就避免了不断的创建连接, 不断的释放连接的过程,从而一定程序上显著的提高程序的性能.
- 能不能自己去定义连接池呢?
连接池 是非常重要的优化技术,那么sun 公司也将 连接池优化技术 集成到了jdbc的api 中.
进入到jdk的api 中,就可以找到相关的接口类.
如果要自定义连接池, 那么只需要去实现这个接口就可以了.
1.自定义的连接池的实现:
可以参考
(1).构造方法初始化连接池
(2).取出连接池中的连接
(3).把用完的连接放回的连接池中去addBack2Pool
2.使用自定义的连接池
引出需要对close方法进行加强
10-12.java中对方法加强
继承----匿名内部类
装饰设计模式
动态代理(最合适)
@Test
public void test3(){
//这个是 会抓老鼠的猫 , 要产生这个猫的一个 代理
final ICat cat = new Cat();
// interfaces --- 要的是 真实的 要产生 是哪个 类的代理对象
ICat proxyCat = (ICat) Proxy.newProxyInstance(MethodEnhancement.class.getClassLoader(), cat.getClass().getInterfaces(), new InvocationHandler() {
/**
* @param proxy --- 代理对象
* @param method --- 调用的 方法 对象 (将调用方法 当作一个method 对象传递进来了 )
* @param args --- 将调用方法 的时候, 传递的参数 封装到一个Object[] 中传递进来了
*
*
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(method.getName().equals("run")){
//说明调用的是 run方法
// 加强 一下
System.out.println("小黑 不愧是 猫 中 战斗机 ...");
//调用 原有的逻辑
return method.invoke(cat, args);
}
return method.invoke(cat, args);
}
});
// proxyCat 代理 猫
//当调用了 代理 对象的任何的方法的时候, 都会 执行 invoke方法里的逻辑
// proxyCat.run();
// proxyCat.hashCode();
}
}
13.使用动态代理改造之前的连接池类
14.c3p0的介绍
15.使用c3p0连接池
c3p0-config.xml
C3P0Test.java
1.不使用配置文件
2.使用配置文件
16.使用c3p0连接池改造之前的工具类
17.今天的内容小结
回滚的异常要设置到最大,避免无法回滚
事务 : 围绕着一个业务功能,展开一组操作, 这组 要么全成功,要么不成功.
管理事务的命令:
开启事务: start transaction;
回滚事务: rollback;
提交事务: commit;
Jdbc 程序中如何管理事务 :
管理事务的代码 要敲会
- 事务特性--- ACID
- 数据库连接池技术:
核心思想
-
对方法进行加强
匿名内部类
装饰者 --- 包装
动态代理
- C3p0连接池的使用:
通过配置文件去配置连接池, 获得连接 对象
18.作业:
- 将jdbc管理事务的代码
- 数据库事务的隔离性问题--- 打开两个窗口, 自己演示
- C3p0 去改造之前的工具类
-
自定义的连接池 -- 选作