关于JDBC中关于Connection的两个疑问:
 
1.Connection实例是线程安全的吗?
    即一个connection实例,在多线程环境中是否可以确保数据操作是安全的?
private static Connection connection;  
    上述代码,设计会不会有问题? 一个Connection实例,即对应底层一个TCP链接,有些开发者可能考虑到"性能",就将代码写成上述样式,最终一个application中所有 的DB操作,使用一个connection.确实减少了与DB的TCP链接个数,但是这真的安全吗??真的提升了性能了吗??
    1) 似乎一个初学者都不会这些写,因为没有sample是这么展示的.但是往往会在每个方法调用时都新建connection,然后close();
    2) 当一个开发者考虑到性能的时候,可能会写出上面的代码..
 
     Connection不是线程安全的,它在多线程环境中使用时,会导致数据操作的错乱,特别是有事务的情况.connection.commit()方法就是提交事务,你可以想象,在多线程环境中,线程A开启了事务,然后线程B却意外的commit,这该是个多么纠结的情况.
 
    如果在没有事务的情况下,且仅仅是简单的SQL Select操作,似乎在不会出现数据错乱,一切看起来比较安全.但是这并非意味着提升了性能, JDBC的各种实现中,connection的各种操作都进行了同步:
##PreparedStatement  
public int executeUpdate(){  
     synchronized(connection){  
        //do      
    }  
}  
同时只有当DB操作完成之后,方法调用才会返回. 尽管connection实例的个数唯一,但是在并发环境中,connection实例上锁竞争是必然的,反而没有提升性能(并发量).
通常情况下,一个Connection实例只会在一个线程中使用,使用完之后close().
    TCP链接的创建开支是昂贵的,当然DB server所能承载的TCP并发连接数也是有限制的.因此每次调用都创建一个Connection,这是不现实的;所以才有了数据库连接池的出现.
    数据库连接池中保持了一定数量的connection实例,当需要DB操作的时候"borrow"一个出来,使用结束之后"return"到连接池中,多线程环境中,连接池中的connection实例交替性的被多个线程使用.
 
2. 在使用dataSourcePool的情况下,一个线程中所有的DB操作使用的是同一个connection吗??
    比如线程A,依次调用了2个方法,每个方法都进行了一次select操作,那么这两个select操作是使用同一个connection吗?
    第一感觉就是: dataSourcePool本身是否使用了threadLocal来保存线程与connection实例的引用关系;如果使用了 threadLocal,那么一个线程多次从pool中获取是同一个connection,直到线程消亡或者调用向pool归还资源..
    如果在spring环境中(或者其他ORM矿建中),这个问题需要分2种情况:事务与非事务.
 
    在非事务场景下,一切都很简单,每一次调用,都是从pool中取出一个connection实例,调用完毕之后归还资源,因此多次调用,应该是不同的connection实例.
public List<Object> select(String sql){  
    Connection connection = pool.getConnection();  
    //do  
    pool.release(connection);//归还资源  
}  
 
    在 使用事务的场景下,情况就有所不同,开启一个新事务的同时,就会冲pool中获取一个connection实例,并 将transaction和connection互为绑定,即此transaction中只会使用此connection,此connection此时只会在一个transaction中使用;
因此,在此事务中,无论操作了多少次DB,事实上只会是一个connection实例,直到事务提交或者回滚,当事务提交或者回滚时,将会解除transaction与connection的绑定关系,同时将connection归还到pool中.
 
 
//开启事务  
public TransactionHolder transaction(){  
    Connection connection = pool.getConnection();  
    connection.setAutoCommit(false);  
    return new TransactionHolder(connection);  
}  
 
//执行sql  
public boolean insert(String sql,TransactionHolder holder){  
    Connection connection = holder.getConnection();  
    //do  
    try{  
        //doInsert  
        return true;  
    }catch(Exception e){  
        holder.setRollback(true);  
    }  
    return false;  
}  
 
//提交事务  
public void commit(TransactionHolder holder){  
    Connection connection = holder.getConnection();  
    connection.commit();  
    holder.unbind();//解除绑定  
    pool.release(connection);//归还资源  
}  
    在有事务的情况上,伪代码可能就像上述例子.对于跨DB分布式事务,可能更加的复杂. 

JDBC Connection的更多相关文章

  1. org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection 原因

    org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection 可能出现的原因     ...

  2. Jmeter组件7. JDBC Connection Configuration & JDBC Request

    Jmeter同样可以测试数据库的性能,通过执行增删改查的语句,以下举的是oracle的例子 Step 1: 下载ojdbc14.jar包放到Jmeter lib包中,在test plan中配置,并且重 ...

  3. Weblogic常见故障常:JDBC Connection Pools(转)

    WebLogic Server中数据库连接池是一个经常出问题的地方,总结一下出问题的原因和解决办法. 一.数据库连接泄漏 此类问题一般都是由于开发人员没有正确关闭数据库连接造成的.比如使用完Conne ...

  4. 解决Only a type can be imported. com.mysql.jdbc.Connection resolves to a package的报错问题

    写jsp加载数据驱动以后老是提示Only a type can be imported. com.mysql.jdbc.Connection resolves to a package的错误,然而改成 ...

  5. Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException:

    七月 17, 2014 4:56:01 下午 org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service( ...

  6. Weblogic常见故障一:JDBC Connection Pools

    最近系统老是出现数据库连接池不够用的问题,由于weblogic数据源里没有配置JDBC连接数,取的是默认值15,太小导致connection耗尽,是不是就报一堆错.后来通过修改WebLogic数据源配 ...

  7. [原理][源代码解析]spring中@Transactional,Propagation.SUPPORTS,以及 Hibernate Session,以及jdbc Connection关系---转载

    问题: 一. 1. Spring 如何处理propagation=Propagation.SUPPORTS? 2. Spring 何时生成HibernateSession ? 3. propagati ...

  8. 【错误】:Could not open JDBC Connection for transaction; nested exception is: Communications link failure;The last packet sent successfully to the server was 1 milliseconds ago

    # #错误日志 2016-11-10 16:19:20,834 ERROR [org.quartz.core.JobRunShell] - Job DEFAULT.jobtask threw an u ...

  9. [原理][来源解析]spring于@Transactional,Propagation.SUPPORTS,以及 Hibernate Session,以及jdbc Connection关联

    Spring 捆绑Hibernate. 夹: 一.  1. Spring 怎样处理propagation=Propagation.SUPPORTS? 2. Spring 何时生成HibernateSe ...

  10. 转:JMeter 参数化之利用JDBC Connection Configuration从数据库读取数据并关联变量

    1.   下载mysql jar包 下载mysql jar包 http://dev.mysql.com/downloads/connector/j/ 网盘下载地址:mysql-connector-ja ...

随机推荐

  1. reverse(), extend(), sort() methods of list

    >>> l = list('sdf') >>> l ['s', 'd', 'f'] >>> id(l) 4520422000 >>&g ...

  2. 获取当前匹配元素 包括自身的html

    $(".test").prop("outerHTML"); 来自为知笔记(Wiz)

  3. HDU 4608 I-number 2013 Multi-University Training Contest 1

    定义一个数 y 为 x 的 I-number.对于 y 有如下要求: 1.y > x; 2.y 的每一位之和要为10的倍数(例如 28 每一位之和为 10 ,为 10 的 1 倍); 3.这样的 ...

  4. linux的命令(1)

    系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS ...

  5. Windows 8 电话激活密钥。(更新至 2013-07-21)

    MAK密钥,可用于电话激活专业版&企业版,2013.7.21 更新,共22枚: slmgr.vbs -ipk MQJNQ-G2TKM-YJP7W-CCXVY-VQR92slmgr.vbs -i ...

  6. MySQL与Oracle 差异比较之七用户权限

    用户权限 编号 类别 ORACLE MYSQL 注释 1 创建用户 Create user user_name identified by user_password default tablespa ...

  7. Datawindow.net 子数据窗口出错

    devexpress通过标签页面打开用户控件,数据窗口嵌入用户控件中.当点击数据窗口含下拉数据窗口字段时出现如下错误: 未处理 System.NullReferenceException Messag ...

  8. 嵌入式 VFS: Cannot open root device "mtdblock2" or unknown-block(2,0)

    系统启动后,虽然nand驱动表现正常,但是最后挂载rootfs时候出错: Kernel command line: root=/dev/mtdblock2 rw init=/linuxrc conso ...

  9. 关于jdbc收集

    一.如果我这样获得一个resultset ResultSet rs=statment.execquery("select * from tab"我如何能够从resultset中获得 ...

  10. 正则 提取html标签value

    using System.Text.RegularExpressions; //step2: extract expected info //<h1 class="h1user&quo ...