JDBC(2)

事务


什么是事务?
转账:
1. 给张三账户减1000元
2. 给李四账户加1000元


当给张三账户减1000元后,抛出了异常!这会怎么样呢?我相信从此之后,张三再也不敢转账了。


使用事务就可以处理这一问题:把多个对数据库的操作绑定成一个事务,要么都成功,要么都失败!


==============


事物的特性:ACID


* 原子性:事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。
* 一致性:事务执行后,数据库状态与其它业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。
* 隔离性:隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。
* 持久性:一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。


==============


MySQL操作事务


1. 开始事务:start transaction
2. 结束事务:commit或rollback


==============


JDBC事务


1. 开始事务:con.setAutoCommit(false);
2. 结束事务;con.commit()或con.rollback();


==============


保存点


保存点的是可以回滚到事务中的某个位置,而不是回滚整个事务。
回滚到保存点不会结束事务。
设置保存点:Savepoint sp = con.setSavepoint();
回滚到保存点:con.rollback(sp);


==============


事务隔离级别


* 脏读:读到未提交
* 不可重复读:两次读取不一致,读取到另一事务修改的记录
* 幻读:两次读取不一致,读取到另一事务插入的记录


--------------


四大隔离级别
* SERIALIZABLE(串行化):对同一数据的访问是串行的,即非并发的,所以不会出现任何并发问题。易出现死锁,效率太低!不可用!
* REPEATABLE READ(可重复读):防止了脏读、不可重复读,但没有防止幻读
* READ COMMITTED(读已提交):防止了脏读,但没有防止不可重复读,以及幻读
* READ UNCOMMITTED(读未提交):可能出现所有并发问题,效率最高,但不可用!


MySQL默认事务隔离级别为:REPEATABLE READ
Oracle默认事务隔离级别为:READ COMMITTED


--------------


MySQL设置事务隔离级别
* 查看:select @@tx_isolation
* 设置:set transaction isolation level 四选一


JDBC设置事务隔离级别
con.setTransactionIsolation(四选一)


===============


数据库连接池


作用:使用池来管理连接的生命周期,节省资源,提高性能。
java提供的连接池接口:javax.sql.DataSource,连接池厂商的连接池类需要实现这一接口。


-------------


DBCP


jar:commons-pool.jar、commons-dbcp.jar


BasicDataSource ds = new BasicDataSource();
ds.setUsername("root");
ds.setPassword("123");
ds.setUrl("jdbc:mysql://localhost:3306/mydb1");
ds.setDriverClassName("com.mysql.jdbc.Driver");
 
ds.setMaxActive(20); 
ds.setMaxIdle(10); 
ds.setInitialSize(10) ;
ds.setMinIdle(2) ;
ds.setMaxWait(1000) ;

Connection con = ds.getConnection();


-------------


C3P0(*****)

使用c3p0数据库连接池是需要配置文件的

要求必须给出c3p0-config.xml不理解请看配置文件中的注释,下面为该配置文件


<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默认配置,当使用ComboPooledDataSource无参构造器时,使用的就是这个配置 -->
<default-config>
<!-- 基本配置 -->
<property name="jdbcUrl">jdbc:mysql://localhost:3306/事物</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">123</property>
<!-- 每次增量,当需要创建Connection对象时,一次创建几个 -->
<property name="acquireIncrement">3</property>
<!-- 当创建池对象后,池中应该有几个Connection对象 -->
<property name="initialPoolSize">10</property>
<!-- 池中最少Connection个数,如果少于这个值,就会创建Connection -->
<property name="minPoolSize">2</property>
<!-- 池中最大连接个数 -->
<property name="maxPoolSize">10</property>
</default-config>
<!-- 命名配置,new ComboPooledDataSource("oralce-config")时,使用的就是这个配置 -->
<named-config name="oracle-config">
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb1</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">123</property>
<property name="acquireIncrement">3</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">2</property>
<property name="maxPoolSize">10</property>
</named-config>
</c3p0-config>





jar:c3p0-0.9.2-pre1.jar、c3p0-oracle-thin-extras-0.9.2-pre1.jar、mchange-commons-0.2.jar


ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setJdbcUrl("jdbc:mysql://localhost:3306/mydb1");
ds.setUser("root");
ds.setPassword("123");
ds.setDriverClass("com.mysql.jdbc.Driver");
 
ds.setAcquireIncrement(5) ;
ds.setInitialPoolSize(20) ;
ds.setMinPoolSize(2) ;
ds.setMaxPoolSize(50) ;

Connection con = ds.getConnection();


Tomcat配置连接池(配置他以后,就不用配置c3p0数据库连接池了)
在server.xml中,或在conf/catalina/localhost/下创建xml文件


<Context>  
  <Resource name="myc3p0" 
type="com.mchange.v2.c3p0.ComboPooledDataSource"
factory="org.apache.naming.factory.BeanFactory"
user="root" 
password="123" 
classDriver="com.mysql.jdbc.Driver"    
jdbcUrl="jdbc:mysql://127.0.0.1/mydb1"
maxPoolSize="20"
minPoolSize ="5"
initialPoolSize="10"
acquireIncrement="2"/>
</Context>  


-------------


获取Tomcat资源
Context cxt = new InitialContext(); 
DataSource ds = (DataSource)cxt.lookup("java:/comp/env/myc3p0");
Connection con = ds.getConnection();


==================

1 ThreadLocal API

ThreadLocal类只有三个方法:

l  void set(T value):保存值;

l  T get():获取值;

l  void remove():移除值。


 * ThreadLocal通常用在一个类的成员上
 * 多个线程访问它时,每个线程都有自己的副本,互不干扰!
 * Spring中把Connection放到了ThreadLocal中!


class User {
private ThreadLocal<String> usernameTl = new ThreadLocal<String>();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值