我有这个类(我的数据库连接工厂):
@ApplicationScoped
public class ConnectionFactory {
private ComboPooledDataSource datasource;
private Long open = 0l;
private Long close = 0l;
@PostConstruct
public void init() throws PropertyVetoException, SQLException {
datasource = new ComboPooledDataSource();
datasource.setDriverClass("org.postgresql.Driver");
datasource.setJdbcUrl("jdbc:postgresql:dbcampanha");
datasource.setUser("postgres");
datasource.setPassword("admin");
datasource.setMinPoolSize(1);
datasource.setMaxPoolSize(5);
datasource.setCheckoutTimeout(30000);
datasource.setUnreturnedConnectionTimeout(30);
datasource.setMaxIdleTime(30);
datasource.setDebugUnreturnedConnectionStackTraces(true);
datasource.setAcquireIncrement(1);
}
@Produces
@RequestScoped
public Connection getConnection() throws ClassNotFoundException {
open++;
try {
Connection connection = datasource.getConnection();
connection.setAutoCommit(false);
return connection;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public void close(@Disposes Connection connection) {
close++;
try {
connection.commit();
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public Long getOpenedConnectionCounter() {
return open;
}
public Long getClosedConnectionCounter(){
return close;
}
public ComboPooledDataSource getDatasource(){
return datasource;
}
}
我将此类与JAX-RS应用程序一起使用。对于使用此路线的一些测试:
@RequestScoped
@Path("/test")
public class TesteService {
@Inject
private Connection connection;
@GET
@Produces(MyMediaType.JSON)
@Path("/yes")
public Response success() throws SQLException {
connection.getClientInfo("");
return Response.ok().build();
}
}
我的客户的这个课程:
public class TesteMain {
private static final String prefix = "http://localhost:8080/schoolwork/service/test/";
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10000; i++) {
Request request = new Request(prefix + "yes");
request.start();
if(i % 10 == 0)
Thread.sleep(1000l);
}
}
public static class Request extends Thread {
private String rota;
public Request(String rota){
this.rota = rota;
}
@Override
public void run() {
try {
HttpURLConnection url = (HttpURLConnection) (new URL(rota).openConnection());
url.connect();
System.out.println(url.getResponseCode() == 200 ? "SUCCESS" : "ERROR");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我收到此信息:
{
"opened-connection": 789,
"closed-connection": 867,
}
是的,我有一些关闭的数据库连接大于打开。怎么样?对此有何想法?
我使用
Tomcat 7 + Java 7
P.S。我很抱歉我的英文不好:/
解决
我更改了AtomicInteger对象的计数器,并且运行正常。
答案 0 :(得分:1)
所以,两个快速评论:
你的计数器是(盒装的)长期读取和更新的1000个并发线程。他们的价值观通常是不可预测和不确定的。他们当然不会准确计算你打算算什么。考虑在AtomicLongs上使用原子操作。
您的commit()
(或rollback()
)应附加到您的数据库业务逻辑中,您可以告诉工作单元成功或失败的部分。你不应该在关闭时自动提交。