简体   繁体   English

Web应用程序的单个数据库连接

[英]Single database connection for web application

I am developing a simple CRUD application, using JDBC to establish connection and perform basic CRUD operations. 我正在开发一个简单的CRUD应用程序,使用JDBC建立连接并执行基本的CRUD操作。 In that process, created a DatabaseListener to create a connection object at startup and storing it in the context attribute for reuse. 在此过程中,创建了一个DatabaseListener来在启动时创建一个连接对象,并将其存储在context属性中以供重用。

Below is the code. 下面是代码。

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.log4j.Logger;

public class DatabaseInitListner implements ServletContextListener {

    private static final Logger LOG = Logger.getLogger(DatabaseInitListner.class);

    private DBUtil databaseUtil = null;

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        databaseUtil.closeConnection();
    }

    @Override
    public void contextInitialized(ServletContextEvent contextinitEvent) {

        ServletContext servletContext = contextinitEvent.getServletContext();
        String database = servletContext.getInitParameter("db_name");
        String url = servletContext.getInitParameter("db_url")
                + database;
        String username = servletContext.getInitParameter("db_user");
        String password = servletContext.getInitParameter("db_password");
        String driverName = servletContext.getInitParameter("db_driver");

        databaseUtil = new DBUtil(url, username, password,
                driverName);
        servletContext.setAttribute("databaseSingleConnectionObject",
                databaseUtil.getConnection());
    }
}

public class DBUtil {
    private Connection connection = null;
    private static final Logger LOG = Logger.getLogger(DatabaseUtil.class);
    public DatabaseUtil(String url, String username, String password,
            String driver) {
        try {
            Class.forName(driver);
            this.connection = DriverManager.getConnection(url, username,
                    password);
            LOG.debug("Connection Established... ");
        } catch (ClassNotFoundException | SQLException e) {
            LOG.error("Could not create connection... ", e);
        }
    }
    public Connection getConnection() {
        return connection;
    }
    public void closeConnection() {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                LOG.error("Unable to close connection... ", e);
            }
        }
    }
}

I am accessing the connection in servlets like this 我正在像这样访问servlet中的连接

Connection jdbcConnection = (Connection) getServletContext().getAttribute("databaseSingleConnectionObject");

I am not sure if this is right approach. 我不确定这是否正确。 What are the effects of single database connection? 单个数据库连接有什么影响?

When you use a single database connection like this you make your application slow and brittle. 当使用这样的单个数据库连接时,会使应用程序变慢且变脆。

Slow: because the connection implementation is synchronized, each user has to wait until the connection is free. 慢:因为连接实现是同步的,所以每个用户都必须等待,直到连接空闲为止。 If one user's query takes a while to come back that directly increases the time any other concurrent users spend waiting. 如果一个用户的查询花了一段时间才返回,则直接增加了其他并发用户等待的时间。 If there were multiple connections available from a pool then the time spent by one user would not impact other users nearly as greatly (unless a query's results take all the JVM's memory or a big query bogs down the database server). 如果池中有多个连接可用,那么一个用户花费的时间不会对其他用户造成几乎相同的影响(除非查询结果占用了所有JVM的内存,或者大查询使数据库服务器瘫痪了)。

Brittle: The connection is a network connection, they tend to go down. 脆弱:连接是网络连接,它们倾向于断开。 Without a provision to create new connections any kind of timeout, network hiccup, or period of database non-availability (such as taking the database offline for maintenance) is going to require an application restart. 如果没有创建新连接的规定,则任何类型的超时,网络故障或数据库不可用的时间段(例如使数据库脱机以进行维护)都将需要重新启动应用程序。 Using a connection pool will mean your application will be able to survive these episodes and recover without outside intervention. 使用连接池将意味着您的应用程序将能够幸免于难,并且无需外部干预即可恢复。

This will not be threadsafe, and if it were, performance would be really poor. 这将不是线程安全的,如果是的话,性能将真的很差。 Look into using a Connection Pool, like DBCP or C3PO 考虑使用连接池,例如DBCP或C3PO

You should let your application server manage database connection. 您应该让您的应用服务器管理数据库连接。 Add a JNDI datasource in its configuration file and make a lookup from your application to get a connection when needed (for instance when you instantiate a class that must access your database). 在其配置文件中添加一个JNDI数据源,并在需要时从您的应用程序进行查找以获得连接(例如,当您实例化必须访问数据库的类时)。 You may configure the datasource to manage a connection pool so that each user session will get its own. 您可以将数据源配置为管理连接池,以便每个用户会话都有自己的连接。 Depending on the AS you use run a search with keywords 'JNDI' and 'datasource' and you will get further details about the AS configuration and how to implement it in your application. 根据您使用的AS,使用关键字“ JNDI”和“ datasource”运行搜索,您将获得有关AS配置以及如何在应用程序中实现它的更多详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM