如果不是同一个Connection的话,事务可能会出问题。
原提问者GitHub用户bscoder1992
Druid连接池通过使用ThreadLocal来实现线程内共享Connection的机制,这样可以保证同一线程中多次获取的Connection是同一个。具体来说,当一个线程第一次从连接池中获取连接时,Druid会在当前线程的ThreadLocal变量中保存连接对象;后续获取连接时,会首先检查ThreadLocal中是否已经存在连接对象,如果存在,则直接返回该连接对象;如果不存在,则会从连接池中获取一个新的连接对象并保存到ThreadLocal中,以便下次使用。
这种方式可以确保在同一线程中,多次获取的Connection对象是同一个,并且可以解决事务问题。因为在同一事务中,需要使用同一个数据库连接来执行多个操作,以保持事务的一致性和隔离性。
请注意,对于不同的线程,Druid连接池会为每个线程分配独立的连接对象。这样可以避免多个线程之间共享同一个Connection对象,从而保证线程安全性。
通过以上机制,Druid连接池可以保证一个线程多次获取的Connection是同一个。如果您有其他疑问,请随时提问。
Druid连接池通过使用ThreadLocal来实现线程内共享Connection的机制,这样可以保证同一线程中获取的Connection是同一个。当一个线程第一次从连接池中获取连接时,Druid会在当前线程的ThreadLocal变量中保存连接对象,后续获取连接时,会首先检查ThreadLocal中是否已经存在连接对象,如果存在,则直接返回该连接对象,否则会从连接池中获取一个新的连接对象并保存到ThreadLocal中,以便下次使用。
此外,Druid还提供了一些配置参数来控制连接池的行为,例如:maxPoolPreparedStatementPerConnectionSize(每个连接池中最大的预编译语句数量)和poolPreparedStatements(是否缓存预编译语句),这些参数可以根据应用的实际情况进行调整,以获得最佳的性能和可靠性。
具体来说,Druid连接池会将连接池中的连接对象保存在一个Map中,Map的key是连接池中的连接对象,value是连接池中的连接对象的引用。当一个线程获取连接池中的连接对象时,Druid连接池会先检查Map中是否已经存在该连接对象的引用,如果存在,则将该连接对象的引用返回给该线程;如果不存在,则创建一个新的连接对象,并将其保存在Map中,以便其他线程也可以获取该连接对象。
你指的多次获取是什么意思呢?是指同一个线程中多次调用DruidDataSource#getConnection()? 如果是上面这个意思的话,Druid自身是保证不了这个事情的吧,要你自己取到一个连接然后保存起来重用吧.
Test code:
`package cn.kenshinn.cube.app.config;
import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidPooledConnection;
import java.sql.SQLException;
/**
Created by kenshinn on 17-7-28. */ public class Test {
public static void main(String[] args) { DruidDataSource druidDataSource = new Test().syncerDataSource(); try { DruidPooledConnection connection = druidDataSource.getConnection(); DruidPooledConnection connection2 = druidDataSource.getConnection(); DruidPooledConnection connection3 = druidDataSource.getConnection();
System.out.println("foo");
} catch (SQLException e) { e.printStackTrace(); }
}
private DruidDataSource syncerDataSource() { DruidDataSource dataSource = new DruidDataSource();
try { dataSourceProperties(dataSource); } catch (Exception e){ e.printStackTrace(); }
return dataSource;
}
private void dataSourceProperties(DruidDataSource dataSource) { String driverClass = "com.mysql.jdbc.Driver"; dataSource.setDriverClassName(driverClass);
String jdbcUrl = "jdbc:mysql://host:3306/test_db?characterEncoding=UTF-8&autoReconnect=true&useSSL=false"; dataSource.setUrl(jdbcUrl);
String username = "user"; dataSource.setUsername(username);
String password = "key"; dataSource.setPassword(password);
Integer initialPoolSize = 1; dataSource.setInitialSize(initialPoolSize);
Integer connMinIdle = 1; dataSource.setMinIdle(connMinIdle);
Integer connMaxActive = 150; dataSource.setMaxActive(connMaxActive);
Integer maxWaitMillis = 60000; dataSource.setMaxWait(maxWaitMillis);
Integer timeBetweenEvictionRunsMillis = 60000; dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
Integer minEvictableIdleTimeMillis = 300000; dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
dataSource.setValidationQuery("SELECT 1"); dataSource.setTestOnBorrow(false); dataSource.setTestWhileIdle(true); dataSource.setTestOnReturn(false);
dataSource.setPoolPreparedStatements(true); dataSource.setMaxPoolPreparedStatementPerConnectionSize(20); try { dataSource.setFilters("stat"); } catch (SQLException e) { e.printStackTrace(); }
// always login dataSource.setLoginTimeout(0);
dataSource.setRemoveAbandoned(true); dataSource.setRemoveAbandonedTimeout(30);
原回答者GitHub用户lynchlee
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。