ThreadLocal + java.sql.Connection + servlet filter = 2009?

I am writing several servlets with the usual old JDBC templates. I realized that I have several objects that would like to share a single transaction, and I would like to apply this HTTP transaction = one database transaction.

I think I can do this by passing Connection in the ThreadLocal variable, and then using a servlet filter that handles the creation / commit / rollback of the specified connection.

Is there an existing structure that does this that I am not attached to, or is it a sensible way to do something late at 00?

+3
source share
5 answers

Spring , , - , , , ( ):

org.springframework.jdbc.datasource.DataSourceTransactionManager org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy org.springframework.transaction.support.TransactionTemplate

DataSource TranscendAwareDataSourceProxy, DataSourceTransactionManager , ServletContext. TransactionTemplate, , execute (TransactionCallback) . :

new TransactionTemplate(transactionManager).execute(new TransactionCallback(){
    public void doInTransaction(TransactionStatus ts){
        // run your code here...use the dataSource to get a connection and run stuff
        Connection c = dataSourceProxy.getConnection();
        // to rollback ... throw a RuntimeException out of this method or call 
        st.setRollbackOnly();
    }
});

, , , .

, spring... , spring spring .

... , , , spring .

+4

appServer todays JTA (Java Transaction Api): , open/close jdbc. "threadLocal" , J2EE. :

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
    UserTransaction transaction = null;
    try {
        transaction = (UserTransaction)new InitialContext().lookup("java:comp/UserTransaction");
        transaction.begin();
        chain.doFilter(request, response);
        transaction.commit();
    } catch (final Exception errorInServlet) {
        try {
            transaction.rollback();
        } catch (final Exception rollbackFailed) {
            log("No ! Transaction failed !",rollbackFailed);
        }
        throw new ServletException(errorInServlet);
    }
}

app- jndi ( cx.commit(), cx.rollback() cx.setAutocommit(), JTA). HTTP-, JTA :

public void doingDatabaseStuff() throws Exception {
    DataSource datasource = (DataSource)new InitialContext().lookup("/path/to/datasource");
    Connection connection = datasource.getConnection();
    try {
        // doing stuff
    } finally {
        connection.close();
    }
}
+1

, " ", ThreadLocal. ServletFilter ServletRequest . , , Connection .

0

- .

Java EE , , Spring, ( ; Spring ).

ThreadLocal . , , , Connection , , - , . , Connection , .

0

"" , Spring, , .

( ) accessor, () setRollbackOnly().

, , , ( ) commit/rollback, .

In most applications and web containers (and the JTA usually makes such assumptions), the request is processed with exactly one thread and linking one database connection to the stream for reuse between layers during the request is the right thing to do.

0
source

Source: https://habr.com/ru/post/1710267/


All Articles