Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为并发性设计数据源连接_Java_Jsp_Servlets_Jdbc_Concurrency - Fatal编程技术网

Java 为并发性设计数据源连接

Java 为并发性设计数据源连接,java,jsp,servlets,jdbc,concurrency,Java,Jsp,Servlets,Jdbc,Concurrency,下面的代码是我们在项目中使用的“基本”servlet: public class MyServlet extends Servlet { private static final long serialVersionUID = 1L; protected Connection conn; /** * @see HttpServlet#HttpServlet() */ public MyServlet() { super();

下面的代码是我们在项目中使用的“基本”servlet:

public class MyServlet extends Servlet {
    private static final long serialVersionUID = 1L;

    protected Connection conn;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public MyServlet() {
        super();
    }

    protected void connectDB() throws NamingException, SQLException {
        // get database settings

        InitialContext cxt = new InitialContext();

        DataSource ds =(DataSource)cxt.lookup( "java:/comp/env/jdbc/MyDB" );
        conn = ds.getConnection();      
    }

    protected void closeDB() throws SQLException {
        try {
            if (conn!=null) conn.close();
        }
        finally {
            conn = null;
        }
    }

    protected void addCacheControl(HttpServletResponse response) {
        response.setHeader("Expires", "Thu, 01 Jan 1970 00:00:00 GMT");
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate, pre-check=0, post-check=0");
        response.setHeader("Pragma", "no-cache");
    }

}
例如,
SomeServlet扩展了MyServlet

现在
SomeServlet
可以在浏览器中访问,它对JSP页面执行
forward()
,然后刷新一段时间(比如10秒)

页面打开一段时间后,此代码抛出NullPointerException:

stmt = conn.prepareCall("{call sp_someSP(?, ?, ?)}");

您不能像这样使用Servlet的实例字段,因为它将由多个线程共享


您需要通过程序显式地将连接作为参数和局部变量传递(以便它们位于堆栈上,每个线程都有自己的版本),或者如果您想要更“全局”的方法,可以使用ThreadLocal。当您的请求完成时,ServletFilter也可以可靠地关闭ThreadLocal连接。

您的意思是从“SomeServlet”我不应该访问“conn”。。。比如stmt=conn.prepareCall({调用sp_someSP(?,?)}”)?不,我的意思是,
conn
字段应该根本不存在。它应该是一个局部变量或ThreadLocal;conn有时只是空的,我的意思是当servlet在浏览器中的多个选项卡中同时被访问时是的,这正是这里的问题所在。您的代码不是线程安全的。如果您想让它在“大部分时间”内正常工作,就需要摆脱非线程安全的共享状态。