java web事务控制_Java实战之04JavaWeb-05事务和连接池

一、事务部分

1.事务的简介

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

2.mysql的事务控制

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

0b3801c385d160964341a77e59cd8a56.png

手动开启事务: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

a50e47ce0f8b6b6654b0b41a4e596f5d.png

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

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

模拟脏读步骤:

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

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

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

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

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

6)A客户端回滚

隔离级别性能问题:serializable

隔离级别安全问题: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 classMyDataSource {2 //1、创建一个池子

3 private static LinkedList datasource = new LinkedList();4 //2、在创建DataSource时 就为池子初始化一些连接资源

5 public MyDataSource(intcount){6 for(int i=0;i

9 Connection conn =JDBCUtils.getConnection();10 //怎样对一个对象中的方法进行加强11 //BufferedReader reader = new BufferedReader(new FileReader(""));

12 ConnectionWrapper wrapper = newConnectionWrapper(conn);13 //在将connnection资源放置到池子中之前 对conn进行一些加强(主要加强是close方法)

14 datasource.add(wrapper);15 } catch(Exception e) {16 e.printStackTrace();17 }18 }19 }20 //获取connection的方法

21 public staticConnection getConnection(){22 returndatasource.removeFirst();23 }24 //将使用完毕的资源放回池子中

25 public static voidgiveBack(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) throwsSQLException {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包

ea793eb7841e5b9b9eb33903d7ea4946.png

1 public classDBCPDemo {2 @Test3 public void test1() throwsSQLException{4 //1、获得一个连接池

5 BasicDataSource dataSource = newBasicDataSource();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 @Test18 public void test2() throwsException{19 InputStream in = DBCPDemo.class.getClassLoader().getResourceAsStream("dbcp.properties");20 Properties pro = newProperties();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包

257d5ee27313f44b46796f8af066d639.png

1 public classC3P0Demo {2 @Test3 public void test1() throwsException{4 //创建连接池

5 ComboPooledDataSource dataSource = newComboPooledDataSource();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 @Test17 public void test2() throwsSQLException{18 //创建连接池19 //ComboPooledDataSource dataSource = new ComboPooledDataSource("haohao");

20 ComboPooledDataSource dataSource = newComboPooledDataSource();21 Connection conn =dataSource.getConnection();22 System.out.println(conn);23 conn.close();24 }25 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值