我想创建一个类的实例,该类可以访问底层的嵌入式derby数据库,并使用声明性服务将该类传递给绑定到数据库包的每个包。
我在derby留档中看到,为多个线程共享一个连接有很多陷阱。所以我在考虑为我正在创建的类的每个实例创建一个连接。由于我只想要一种非常简单的方法来创建多个连接并管理它们,因此在这里使用“MiniConnectionPoolManager”似乎是一个不错的选择。derby的示例代码如下所示:
org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource dataSource = new org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource();
dataSource.setDatabaseName("c:/temp/testDB");
dataSource.setCreateDatabase("create");
MiniConnectionPoolManager poolMgr = new MiniConnectionPoolManager(dataSource, maxConnections);
...
Connection connection = poolMgr.getConnection();
...
connection.close();
但是留档并没有涵盖很多东西,而且我是使用数据库的初学者。我的问题是:
>
我应该何时关闭此连接?我不知道bundle(user)将使用新类多长时间,所以我应该将新创建的连接保存在一个私有全局变量中,并强制用户执行unregister类,然后关闭连接吗?或者,当我的数据库包被停用时,我应该关闭所有连接吗。
对于管理访问一个数据库的不同类,我们也非常感谢其他建议。提前谢谢你。
编辑:
只要应用程序在运行,我的数据库包中的主类就始终处于活动状态。是包请求一个新类的实例(执行数据库操作)来来去去去。而且,由于它将部署在嵌入式系统中,我只能使用占用空间小的应用程序。
您应该在需要时从连接池获得连接,并尽快关闭连接。重用连接是连接池的工作,而不是你的。
换句话说:在停用消费者捆绑包之前,不要保持连接处于活动状态。
连接池通常实现数据源接口,您应该通过它使用池。在这种情况下,您可以轻松地替换池实现,而无需更改代码。E、 g:
@Component
public class MyComponent {
// Connection pool based DataSource
@Reference
DataSource dataSource;
public void myFunction() {
try (Connection c = dataSource.getConnection()) {
// Database operations
} catch (SQLException e) {
// TODO
}
}
}
当您发现自己多次重复相同的代码(获取连接、捕获SQLException)时,您可以编写一个接受功能接口的简单组件。例如:
@Component
@Service
public class SQLHelper {
@Reference // This is a connection pool DataSource
private DataSource dataSource;
public <R> R execute(Callback<R> callback) {
try (Connection c = dataSource.getConnection()) {
return callback.call(c);
} catch (SQLException e) {
throw new UncheckedSQLException(e);
}
}
}
您的功能界面如下所示:
public interface Callback<R> {
R call(Connection connection);
}
您可以这样使用它:
sqlHelper.execute((Connection c) -> {
// Do some stuff with the connection
});
使用事务
如果你想使用原子事务,我建议你应该使用org。阿帕奇。德比。jdbc。EmbeddedXADataSource和org。阿帕奇。平民dbcp。管理。来自commons dbcp的BasicManagedDataSource。之后,您可以通过JTA处理事务。
很难直接使用JTA API。您应该选择一个有助于传播事务的库。
基于声明性服务的小指南:
现在您已经拥有了编写代码的一切。您的组件类似于以下内容:
@Component
@Service
public class MyComponent {
@Reference
private DataSource dataSource;
@Reference
private TransactionHelper th;
public void myFunction() {
th.required(() -> {
try (Connection c = dataSource.getConnection()) {
// My SQL statements
} catch (SQLException e) {
// TODO
}
}
}
}
如果您不需要交易处理,您可以:
更复杂的指南(也负责模式创建和使用基于OO的查询)位于http://cookbook.everit.org/persistence/index.html.
更新
您不必为每个SQL语句获取连接。您应该获得一个连接,在“片刻”内执行尽可能多的SQL语句,然后在连接上调用close。
MiniConnectionPoolManager对于嵌入式设备来说可能是一个很好的解决方案,因为它实际上是“迷你型”的。唯一的问题是它没有实现数据源接口,因此您的业务代码将直接使用MiniCPM类。通过这样做,如果您发现bug或以后需要更复杂的连接池,那么切换到其他连接池将更加困难。
如果您决定使用MiniCPM,我建议您编写一个实现DataSource的组件,并将getConnection()函数委托给MiniCPM实例。E、 g.:
@Component
@Service
public class MiniCPMDataSourceComponent implements DataSource {
@Reference
protected ConnectionPoolDataSource cpDataSource;
private MiniConnectionPoolManager wrapped;
@Activate
public void activate() {
this.wrapped = new MiniConnectionPoolManager(cpDataSource);
}
@Override
public Connection getConnection() {
return wrapped.getConnection();
}
@Override
public Connection getConnection(String user, String password) {
throw new UnsupportedOperationException();
}
@Deactivate
public void deactivate() {
wrapped.dispose();
}
}
您可以使用诸如最大连接数和超时(MiniCPM支持)之类的配置可能性来装饰此组件。如果使用此组件提供的服务,则可以在不更改业务代码的情况下切换连接池。此外,您的业务捆绑包不会直接连接到MiniCPM。
我的web应用程序(将部署在tomcat上)需要一个嵌入式数据库来存储临时用户数据,以便更快地检索。我选择Apache Embedded Derby是因为它很容易嵌入到web应用程序中,而且是一个纯Java DB。 我还实现了连接池来检索连接。我在这里面临着两个关键的问题(显示塞子)。首先,我的应用程序一次不能有两个以上的活动连接。所以,我的应用程序挂断了。 其次,我不断发现另一个应用程序已经启动
我了解到连池的实现是基于提供者的,所以SQL数据提供者的连池工作方式将不同于Oledb的连池。(参考文献:http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx)池的默认最大物理连接是100。如果我们有不同的连接字符串(或不同的字符串顺序,但相同的数据库)或不同的窗口身份(如果我们使用窗口身份验证),新的连接池将被创建。 请让我知道,如果你不清楚
我有这个使用HikariCP连接池的代码: 我通过发出命令“Show Processlist”来监控mysql中的连接,我看到在行之后创建了100个连接: 。。。正在运行。我肯定这不是命中注定的,对吧?它应该在稍后执行pooledDataSource时创建连接。getConnection()。 我做错了什么?为什么它会立即创建100个连接??
我使用具有以下设置的Hikary连接池: 在getConnection()之后,hikari尝试获取到实例的2个连接,但只将一个连接放在连接池中。我怎样才能修好它?hikari版本是
无法使用C3P0创建Hibernate-JPA连接池。面对以下错误日志: 请求请提供一个解决方案如何创建连接池使用JPA在KARAF。
问题内容: 我正在使用JSCH进行sftp文件上传。在当前状态下,每个线程都会在需要时打开和关闭连接。 是否可以在JSCH中使用连接池,以避免由于大量打开和关闭连接而导致的开销? 这是从线程内部调用的函数的示例 问题答案: 为此,我希望使用commons-pool。;)