您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

事务、连接池、开源数据源(DBCP、C3P0)

2024/4/6 2:23:10发布18次查看
事务的概念 事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部不成功。 例如:a——b转帐,对应于如下两条sql语句 update account set money=money-100 where name=‘a’; update account set money=money100 where name=‘b’; 数据
事务的概念
事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部不成功。
例如:a——b转帐,对应于如下两条sql语句
update account set money=money-100 where name=‘a’;
update account set money=money+100 where name=‘b’;
数据库开启事务命令dtl
start transaction 开启事务
rollback 回滚事务
commit 提交事务
一、事务
a、数据库中的dtl:database transaction language
开启事务:start transaction
提交事务:commit
回滚事务:rollback
数据库:mysql,一般情况下,事务是自动开启和关闭的。
手工控制事务:使用dtl
b、jdbc中控制事务的执行
开启事务:start transaction connection.setautocommit(false)
提交事务:commit connection.commit()
回滚事务:rollback connection.rollback()
c、事务的特性:(理论)
a原子性:比喻处于同一个事务中的多条语句是不可分割的单位
c一致性:比如:a1000 b1000 执行事务前:a+b=2000 执行事务后a+b=2000
i隔离性:事务执行过程中不应该被其他线程的事务所干扰。
d持久性:事务结束后,操作的数据应该被永久性的保存起来(磁盘上)
********************************************************************************************
专题:隔离性(很重要)
前提:多线程并发操作数据库中的数据
不考虑事务隔离性,会出现以下问题:
1、脏读:a线程读取到了b线程未提交的数据
2、不可重复读:a线程读到了b线程提交的更新(update)后的数据
3、虚读:a线程读到了b线程提交的插入(insert)后的数据
a、mysql控制事务的隔离级别
read uncommitted:脏读、不可重复读、虚读都有可能发生
read committed:防止脏读的发生,不可重复读、虚读都有可能发生(oracle默认的级别)
repeatable read:防止脏读、不可重复读,虚读有可能发生(mysql默认的级别)
serializable:防止脏读、不可重复读、虚读
mysql:
查看当前事务的隔离级别:select @@tx_isolation;
更改当前线程事务的隔离级别:set transaction isolation level 四个级别之一;
b、jdbc控制事务的隔离级别
connection:transaction_read_uncommitted
connection:transaction_read_committed
connection:transaction_repeatable_read
connection:transaction_serializable
connection.settransactionisolation(int level):开启事务之前调用。
conn.settransactionisolation(connection.transaction_repeatable_read);
//开启事务
conn.setautocommit(false);
二、数据库连接池
1、标准的连接池要实现javax.sql.datasource接口
2、编程核心:
当用户调用connection.close()(实际上是调用的数据库驱动中的对应实现方法),把当前用到的连接换回原来的连接池中,已达到复用的目的。
不能去该数据库的驱动的实现。改写已知类的某个或某些方法的原有行为。
解决方案:
a、继承(行不通):myconnection extends ?(不能与具体数据库有关) com.mysql.jdbc.connection
b、包装(装饰):
1、编写一个类,实现与被包装类相同的接口 public class myconnection implements connection{}
2、定义一个成员变量,引用被包装的对象的实例 private connection conn;
3、定义构造方法,传入被包装的对象的实例 public myconnection(connection conn){this.conn = conn;}
4、对于不需要改变的方法,调用原有对象的对应方法 public void commit(){conn.commit();}
5、对于需要改变的方法,你该就完了。 public void close(){//把连接放回池中}
变化:
1、编写一个类,继承已经实现了被包装对象接口的类
2、定义一个成员变量,引用被包装的对象的实例
3、定义构造方法,传入被包装的对象的实例
4、对于需要改变的方法,覆盖就完了
c、动态代理:
实现拦截功能:方法执行前,方法执行后,方法遇到异常,方法中的finally,从而实现aop(aspect-oriented programming面向切面)编程
1、基于接口的动态代理:借助jdk中的reflect.proxy
2、基于子类的动态代理:借助第三方的开源项目。cglib
使用前提:被代理对象的类
a、必须是public的,有默认的构造方法
b、不能是final的
三、开源数据源的使用
1、dbcp(常用)
commons-dbcp.jar:连接池的实现
commons-pool.jar:连接池实现的依赖库
dbcpconfig.properties配置文件如下:
#连接设置driverclassname=com.mysql.jdbc.driverurl=jdbc:mysql://localhost:3306/day16username=rootpassword=sorry#initialsize=10#最大连接数量maxactive=50#maxidle=20#minidle=5#maxwait=60000#jdbc驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] #注意:user 与 password 两个属性会被明确地传递,因此这里不需要包含他们。connectionproperties=useunicode=true;characterencoding=utf8#指定由连接池所创建的连接的自动提交(auto-commit)状态。defaultautocommit=true#driver default 指定由连接池所创建的连接的只读(read-only)状态。#如果没有设置该值,则“setreadonly”方法将不被调用。(某些驱动并不支持只读模式,如:informix)defaultreadonly=#driver default 指定由连接池所创建的连接的事务级别(transactionisolation)。#可用值为下列之一:(详情可见javadoc。)none,read_uncommitted, read_committed, repeatable_read, serializabledefaulttransactionisolation=repeatable_read
import java.io.inputstream;import java.sql.connection;import java.sql.sqlexception;import java.util.properties;import javax.sql.datasource;import org.apache.commons.dbcp.basicdatasourcefactory;public class dbcputil { private static datasource datasource; static{ try { inputstream instream = dbcputil.class.getclassloader().getresourceasstream(dbcpconfig.properties); properties props = new properties(); props.load(instream); datasource = basicdatasourcefactory.createdatasource(props); } catch (exception e) { throw new exceptionininitializererror(初始化数据库配置文件失败); } } public static connection getconnection() throws sqlexception{ return datasource.getconnection(); }}
2、c3p0
发行包\lib\全考
c3p0-config.xml配置文件:文件名是固定的写法
com.mysql.jdbc.driver jdbc:mysql:///day16 root sorry 15 20 5 200
import java.sql.connection;import java.sql.sqlexception;import com.mchange.v2.c3p0.combopooleddatasource;public class c3p0util { private static combopooleddatasource datasource = new combopooleddatasource(); public static connection getconnection() throws sqlexception{ return datasource.getconnection(); }}
3、用服务器提供的数据源的配置(具体参考服务器的文档)
以tomcat为例(用的就是dbcp)
a、拷贝数据库驱动jar到tomcat\lib目录下
b、在你应用的meta-inf目录下建立一个context.xml配置文件
c、重新启动tomcat,服务器就按照配置创建好了数据源,在jndi容器中。
jndi:javaee技术之一。java naming and directory interface
(就是一个map,map的key是一个string,是一个目录, value就是绑定的对象。 类似window系统的注册表)
api存在jdk的javax.naming.*包中。
d、在tomcat管理的web应用中才能使用,不能在main方法中运行,不是同一个虚拟机。
context initcontext = new initialcontext();
datasource ds = (datasource)initcontext.lookup(java:/comp/env/jdbc/day16);
connection conn = ds.getconnection();
import java.sql.connection;import javax.naming.context;import javax.naming.initialcontext;import javax.sql.datasource;public class jndidstest { //和tomcat不是一个虚拟机 public static void main(string[] args) throws exception { context initcontext = new initialcontext(); datasource ds = (datasource)initcontext.lookup(java:/comp/env/jdbc/day16); connection conn = ds.getconnection(); system.out.println(conn); }}
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product