You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by am...@netscape.net on 2006/03/14 17:30:53 UTC

MySQL JDBC Exception: "No operations allowed after connection closed"

I use Tomcat 5.0.28 on both Fedora and FreeBSD, MySQL 4.1.14, 
J/Connector JDBC driver for MySQL 3.1.11 and JOTM 2.0.10. From time to 
time I get the MySQL JDBC driver exception "No operations allowed after 
connection closed", after which DB calls from my application keep 
failing. The stack trace of the exception is as follows:

java.sql.SQLException: No operations allowed after connection closed.
        at com.mysql.jdbc.Connection.checkClosed(Connection.java:1831)
        at com.mysql.jdbc.Connection.setAutoCommit(Connection.java:4866)
         at 
org.enhydra.jdbc.core.CoreConnection.setAutoCommit(CoreConnection.java:23
4)
         at 
org.enhydra.jdbc.standard.StandardXAConnectionHandle.setAutoCommit(Standa
rdXAConnectionHandle.java:123)
         at 
org.enhydra.jdbc.standard.StandardXAConnectionHandle.prepareStatement(Sta
ndardXAConnectionHandle.java:220)
         at 
org.enhydra.jdbc.standard.StandardXAConnectionHandle.prepareStatement(Sta
ndardXAConnectionHandle.java:197)
         at 
com.kc.ppt.dao.mysql.UserDeviceDAOImpl.updatePhoneNumber(UserDeviceDAOImp
l.java:499)
         at 
com.kc.ppt.bo.UserDeviceBO.updateUserDeviceNumber(UserDeviceBO.java:187)
        at com.kc.ppt.bo.UserBO.addUserProfile(UserBO.java:188)
        at com.kc.ppt.bapi.BAPIImpl.addUserProfile(BAPIImpl.java:97)
         at 
com.kc.ppt.servlet.CreateUserProfileServlet.processRequest(CreateUserProf
ileServlet.java:262)
         at 
com.kc.ppt.servlet.CreateUserProfileServlet.doPost(CreateUserProfileServl
et.java:123)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
         at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applicat
ionFilterChain.java:252)
         at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilte
rChain.java:173)
         at 
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve
.java:214)
         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveCon
text.java:104)
         at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:52
0)
         at 
org.apache.catalina.core.StandardContextValve.invokeInternal(StandardCont
extValve.java:198)
         at 
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve
.java:152)
         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveCon
text.java:104)
         at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:52
0)
         at 
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:
137)
         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveCon
text.java:104)
         at 
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:
118)
         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveCon
text.java:102)
         at 
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:535)

         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveCon
text.java:102)
         at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:52
0)
         at 
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.j
ava:109)
         at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveCon
text.java:104)
         at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:52
0)
         at 
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)

When defining datasources in the application's context.xml I tried both 
the new recommended configuration for MySQL J/Connector JDBC driver 
(shown for Resource name="jdbc/primaryDS") and the "autoreconnect=true" 
approach (shown for Resource name="jdbc/primaryDS"). Please note that I 
did not mix those two approaches, I just used different datasources to 
indicate configurations that I used. Does anybody know if the new MySQL 
J/Connector configuration works with Tomcat? Here's my context.xml file:

<Context path="/myapp" docBase="myapp"
            debug="5" reloadable="true" crossContext="true">

        <Logger className="org.apache.catalina.logger.FileLogger"
               prefix="localhost_myapp_log." suffix=".txt"
               timestamp="true"/>

        <!-- Primary AV data source -->
        <Resource name="jdbc/primaryDS"
               auth="Container"
               type="javax.sql.DataSource"/>

        <ResourceParams name="jdbc/primaryDS">
                <parameter>
                        <name>factory</name>
                         
<value>org.objectweb.jndi.DataSourceFactory</value>
                </parameter>

                 <!-- Maximum number of dB connections in pool. 
Configure mysqld
                          max_connections large enough to handle all DB 
connections.
                         Set to 0 for no limit.
                -->

                <parameter>
                        <name>maxActive</name>
                        <value>100</value>
                </parameter>

                 <!-- Maximum number of idle dB connections to retain in 
pool.
                         Set to 0 for no limit.
                -->
                <parameter>
                        <name>maxIdle</name>
                        <value>30</value>
                </parameter>

                 <!-- Don't use autoReconnect=true, it's going away 
eventually
                  and it's a crutch for older connection pools that 
couldn't
                  test connections. You need to decide whether your 
application is
                  supposed to deal with SQLExceptions (hint, it should), 
and
                 how much of a performance penalty you're willing to pay
                 to ensure 'freshness' of the connection -->

                <parameter>
                      <name>validationQuery</name>
                      <value>SELECT 1</value>
                 </parameter>

                <!-- The most conservative approach is to test 
connections
                     before they're given to your application. For most 
applications
                     this is okay, the query used above is very small 
and takes
                     no real server resources to process, other than the 
time used
                    to traverse the network.

                     If you have a high-load application you'll need to 
rely on
                    something else. -->

                    <parameter>
                      <name>testOnBorrow</name>
                      <value>true</value>
                    </parameter>

                   <!-- Otherwise, or in addition to testOnBorrow, you 
can test
                    while connections are sitting idle -->

                <parameter>
                      <name>testWhileIdle</name>
                      <value>true</value>
                </parameter>

                <!-- You have to set this value, otherwise even though
                     you've asked connections to be tested while idle,
                     the idle evicter thread will never run -->

                <parameter>
                      <name>timeBetweenEvictionRunsMillis</name>
                      <value>10000</value>
                </parameter>

                <!-- Don't allow connections to hang out idle too long,
                      never longer than what wait_timeout is set to on 
the
                     server...A few minutes or even fraction of a minute
                      is sometimes okay here, it depends on your 
application
                     and how much spikey load it will see -->
                <parameter>
                  <name>minEvictableIdleTimeMillis</name>
                  <value>60000</value>
                </parameter>

                 <!-- MySQL dB username and password for dB connections  
-->
                <parameter>
                        <name>username</name>
                        <value>myuser</value>
                </parameter>

                <parameter>
                        <name>password</name>
                        <value>mypasswd</value>
                </parameter>

                <!-- Class name for mm.mysql JDBC driver -->

                <parameter>
                        <name>driverClassName</name>
                        <value>com.mysql.jdbc.Driver</value>
                </parameter>

                <parameter>
                        <name>url</name>
                         
<value>jdbc:mysql://10.10.10.10:3306/mydb</value>
                </parameter>
        </ResourceParams>

       <!-- Secondary AV data source -->
        <Resource name="jdbc/secondaryDS"
               auth="Container"
               type="javax.sql.DataSource"/>

        <ResourceParams name="jdbc/secondaryDS">
                <parameter>
                        <name>factory</name>
                         
<value>org.objectweb.jndi.DataSourceFactory</value>
                </parameter>

                 <!-- Maximum number of dB connections in pool. 
Configure mysqld
                          max_connections large enough to handle all DB 
connections.
                         Set to 0 for no limit.
                -->

                <parameter>
                        <name>maxActive</name>
                        <value>10</value>
                </parameter>

                 <!-- Maximum number of idle dB connections to retain in 
pool.
                         Set to 0 for no limit.
                -->
                <parameter>
                        <name>maxIdle</name>
                        <value>10</value>
                </parameter>

                 <!-- Maximum time to wait for a dB connection to become 
available
                          in ms, in this example 10 seconds. An 
Exception is thrown if
                          this timeout is exceeded.  Set to -1 to wait 
indefinitely.
                -->
               <parameter>
                        <name>maxWait</name>
                        <value>10000</value>
                </parameter>

                 <!-- MySQL dB username and password for dB connections  
-->
                <parameter>
                        <name>username</name>
                        <value>myuser</value>
                </parameter>

                <parameter>
                        <name>password</name>
                        <value>mypasswd</value>
                </parameter>

                <!-- Class name for mm.mysql JDBC driver -->

                <parameter>
                        <name>driverClassName</name>
                        <value>com.mysql.jdbc.Driver</value>
                </parameter>

                <!-- The JDBC connection url for connecting to MySQL dB.
                          The autoReconnect=true argument to the url 
makes sure that the
                          mm.mysql JDBC Driver will automatically 
reconnect if mysqld closed the
                          connection.  mysqld by default closes idle 
connections after 8 hours.
                -->

                <parameter>
                        <name>url</name>
                         
<value>jdbc:mysql://10.10.10.11:3306/mydb?autoReconnect=true</value>
                </parameter>
        </ResourceParams>

        <!-- Description of the resource user transaction -->
         <Resource name="jdbc/tx" auth="Container" 
type="javax.transaction.UserTransaction" />

        <ResourceParams name="jdbc/tx">
                <parameter>
                        <name>factory</name>
                         
<value>org.objectweb.jotm.UserTransactionFactory</value>
                </parameter>

                <parameter>
                        <name>jotm.timeout</name>
                        <value>60</value>
                </parameter>
        </ResourceParams>
</Context>

The method that starts the transaction looks as follows:

public User addUserProfile(User newUser, User existingUser,
            UserDevice userDevice, UserRegistrationType regType)
            throws BOException {
        boolean success = false;

        try {
            userTx.begin();
             userBO.addUserProfile(newUser, existingUser, userDevice, 
regType);
            success = true;
        } catch (NotSupportedException nse) {
            logger.warn("Tx - operation not supported", nse);
        } catch (SystemException se) {
            logger.warn("Tx - system exception", se);
        } finally {
            try {
                if (success) {
                    /*
                     * Transaction was successful, commit it.
                     */
                    userTx.commit();
                } else {
                    /*
                     * Transaction failed, roll it back.
                     */
                    userTx.rollback();
                }
            } catch (Exception e) {
                // Report problem to the client
                success = false;
            }
        }

        return newUser;
    }

The method that invokes the DAO layer:

public void updateUserDeviceNumber(UserDevice userDevice, PhoneNumber 
number)
            throws BOException {
        try {
            getUserDeviceDAO().updatePhoneNumber(userDevice, number);
        } catch (DAOException daoe) {
            throw new BOException(daoe);
        }
    }

The DAO method that throws the SQLException:

     public void updatePhoneNumber(UserDevice userDevice, PhoneNumber 
number)
            throws DAOException {

        Connection conn = null;
        PreparedStatement prepStmt = null;

        try {
            conn = MySQLDataStore.getInstance().getConnection();
            prepStmt = conn.prepareStatement(UPDATE_PHONE_NUMBER_STMT);

            prepStmt.setLong(1, number.getCountryCode());
            prepStmt.setLong(2, number.getAreaCode());
            prepStmt.setLong(3, number.getLocalNumber());
            prepStmt.setLong(4, userDevice.getId());

            prepStmt.execute();

        } catch (SQLException sqle) {
             logger.warn("Failed to update user phone number for device: 
"
                    + userDevice.getId(), sqle);
            throw new DAOException(sqle);
        } finally {
            MySQLDataStore.getInstance().close(prepStmt, conn);
            prepStmt = null;
            conn = null;
        }
    }

Connections are retrieved in the following way:

public Connection getConnection() throws SQLException {
    if (primaryDS == null) {
        primaryDS = (DataSource) ctx.lookup(DataSourceNames.PRIMARY_DS);
    }
    return primaryDS.getConnection();
}

And the statement and connection are closed as follows:

public void close(PreparedStatement ps, Connection conn) {
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException sqle) {
                avLogger.warn("Failed to close statement: " + ps, sqle);
            }
        }

            if (conn != null) {
            try {
                conn.close();
            } catch (Exception ex) {
                logger.debug(
                        "Exception when closing connection: "
                                + conn, ex);
            }
        }
    }


___________________________________________________
Try the New Netscape Mail Today!
Virtually Spam-Free | More Storage | Import Your Contact List
http://mail.netscape.com


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: MySQL JDBC Exception: "No operations allowed after connection closed"

Posted by am...@netscape.net.
The fact that I use JOTM with Tomcat forces me to use a different data 
source factory from the one described in the MySQL document "Using 
Connector/J with Tomcat", 
(http://dev.mysql.com/doc/refman/4.1/en/cj-tomcat-config.html)  - 
org.objectweb.jndi.DataSourceFactory vs. 
org.apache.commons.dbcp.BasicDataSourceFactory. The data source factory 
required for JOTM is specified in the following document: "How to use 
JDBC and transactions in Tomcat with JOTM" 
(http://jotm.objectweb.org/current/jotm/doc/howto-tomcat-jotm.html)

Different data source factories translate into different data sources 
and connections (XA pool vs. DBCP) so I've been wondering if anybody 
knows what parameters should be used to configure XA pool running in 
Tomcat to use the new MySQL driver recommendations (autoReconnect being 
an obsoleted parameter)?

-----Original Message-----
From: amiljusevic@netscape.net
To: users@tomcat.apache.org
Sent: Tue, 14 Mar 2006 11:30:53 -0500
Subject: MySQL JDBC Exception: "No operations allowed after connection 
closed"

   I use Tomcat 5.0.28 on both Fedora and FreeBSD, MySQL 4.1.14, 
J/Connector JDBC driver for MySQL 3.1.11 and JOTM 2.0.10. From time to 
time I get the MySQL JDBC driver exception "No operations allowed after 
connection closed", after which DB calls from my application keep 
failing. The stack trace of the exception is as follows:

 java.sql.SQLException: No operations allowed after connection closed.
 at com.mysql.jdbc.Connection.checkClosed(Connection.java:1831)
 at com.mysql.jdbc.Connection.setAutoCommit(Connection.java:4866)
  at 
org.enhydra.jdbc.core.CoreConnection.setAutoCommit(CoreConnection.java:23

 4)
  at 
org.enhydra.jdbc.standard.StandardXAConnectionHandle.setAutoCommit(Standa

 rdXAConnectionHandle.java:123)
  at 
org.enhydra.jdbc.standard.StandardXAConnectionHandle.prepareStatement(Sta

 ndardXAConnectionHandle.java:220)
  at 
org.enhydra.jdbc.standard.StandardXAConnectionHandle.prepareStatement(Sta

 ndardXAConnectionHandle.java:197)
  at 
com.kc.ppt.dao.mysql.UserDeviceDAOImpl.updatePhoneNumber(UserDeviceDAOImp

 l.java:499)
  at 
com.kc.ppt.bo.UserDeviceBO.updateUserDeviceNumber(UserDeviceBO.java:187) 

 at com.kc.ppt.bo.UserBO.addUserProfile(UserBO.java:188)
 at com.kc.ppt.bapi.BAPIImpl.addUserProfile(BAPIImpl.java:97)
  at 
com.kc.ppt.servlet.CreateUserProfileServlet.processRequest(CreateUserProf

 ileServlet.java:262)
  at 
com.kc.ppt.servlet.CreateUserProfileServlet.doPost(CreateUserProfileServl

 et.java:123)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
  at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applicat

 ionFilterChain.java:252)
  at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilte

 rChain.java:173)
  at 
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve

 .java:214)
  at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveCon

 text.java:104)
  at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:52

 0)
  at 
org.apache.catalina.core.StandardContextValve.invokeInternal(StandardCont

 extValve.java:198)
  at 
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve

 .java:152)
  at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveCon

 text.java:104)
  at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:52

 0)
  at 
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:

 137)
  at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveCon

 text.java:104)
  at 
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:

 118)
  at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveCon

 text.java:102)
  at 
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:535)


  at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveCon

 text.java:102)
  at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:52

 0)
  at 
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.j

 ava:109)
  at 
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveCon

 text.java:104)
  at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:52

 0)
  at 
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)

  When defining datasources in the application's context.xml I tried 
both the new recommended configuration for MySQL J/Connector JDBC 
driver (shown for Resource name="jdbc/primaryDS") and the 
"autoreconnect=true" approach (shown for Resource 
name="jdbc/primaryDS"). Please note that I did not mix those two 
approaches, I just used different datasources to indicate 
configurations that I used. Does anybody know if the new MySQL 
J/Connector configuration works with Tomcat? Here's my context.xml 
file:

 <Context path="/myapp" docBase="myapp"
 debug="5" reloadable="true" crossContext="true">

 <Logger className="org.apache.catalina.logger.FileLogger"
 prefix="localhost_myapp_log." suffix=".txt"
 timestamp="true"/>

 <!-- Primary AV data source -->
 <Resource name="jdbc/primaryDS"
 auth="Container"
 type="javax.sql.DataSource"/>

 <ResourceParams name="jdbc/primaryDS">
 <parameter>
 <name>factory</name>
 <value>org.objectweb.jndi.DataSourceFactory</value>
 </parameter>

 <!-- Maximum number of dB connections in pool. Configure mysqld
 max_connections large enough to handle all DB connections.
 Set to 0 for no limit.
 -->

 <parameter>
 <name>maxActive</name>
 <value>100</value>
 </parameter>

 <!-- Maximum number of idle dB connections to retain in pool.
 Set to 0 for no limit.
 -->
 <parameter>
 <name>maxIdle</name>
 <value>30</value>
 </parameter>

 <!-- Don't use autoReconnect=true, it's going away eventually
 and it's a crutch for older connection pools that couldn't
 test connections. You need to decide whether your application is
 supposed to deal with SQLExceptions (hint, it should), and
 how much of a performance penalty you're willing to pay
 to ensure 'freshness' of the connection -->

 <parameter>
 <name>validationQuery</name>
 <value>SELECT 1</value>
 </parameter>

 <!-- The most conservative approach is to test connections
 before they're given to your application. For most applications
 this is okay, the query used above is very small and takes
 no real server resources to process, other than the time used
 to traverse the network.

 If you have a high-load application you'll need to rely on
 something else. -->

 <parameter>
 <name>testOnBorrow</name>
 <value>true</value>
 </parameter>

 <!-- Otherwise, or in addition to testOnBorrow, you can test
 while connections are sitting idle -->

 <parameter>
 <name>testWhileIdle</name>
 <value>true</value>
 </parameter>

 <!-- You have to set this value, otherwise even though
 you've asked connections to be tested while idle,
 the idle evicter thread will never run -->

 <parameter>
 <name>timeBetweenEvictionRunsMillis</name>
 <value>10000</value>
 </parameter>

 <!-- Don't allow connections to hang out idle too long,
 never longer than what wait_timeout is set to on the
 server...A few minutes or even fraction of a minute
 is sometimes okay here, it depends on your application
 and how much spikey load it will see -->
 <parameter>
 <name>minEvictableIdleTimeMillis</name>
 <value>60000</value>
 </parameter>

 <!-- MySQL dB username and password for dB connections -->
 <parameter>
 <name>username</name>
 <value>myuser</value>
 </parameter>

 <parameter>
 <name>password</name>
 <value>mypasswd</value>
 </parameter>

 <!-- Class name for mm.mysql JDBC driver -->

 <parameter>
 <name>driverClassName</name>
 <value>com.mysql.jdbc.Driver</value>
 </parameter>

 <parameter>
 <name>url</name>
 <value>jdbc:mysql://10.10.10.10:3306/mydb</value>
 </parameter>
 </ResourceParams>

 <!-- Secondary AV data source -->
 <Resource name="jdbc/secondaryDS"
 auth="Container"
 type="javax.sql.DataSource"/>

 <ResourceParams name="jdbc/secondaryDS">
 <parameter>
 <name>factory</name>
 <value>org.objectweb.jndi.DataSourceFactory</value>
 </parameter>

 <!-- Maximum number of dB connections in pool. Configure mysqld
 max_connections large enough to handle all DB connections.
 Set to 0 for no limit.
 -->

 <parameter>
 <name>maxActive</name>
 <value>10</value>
 </parameter>

 <!-- Maximum number of idle dB connections to retain in pool.
 Set to 0 for no limit.
 -->
 <parameter>
 <name>maxIdle</name>
 <value>10</value>
 </parameter>

 <!-- Maximum time to wait for a dB connection to become available
 in ms, in this example 10 seconds. An Exception is thrown if
 this timeout is exceeded. Set to -1 to wait indefinitely.
 -->
 <parameter>
 <name>maxWait</name>
 <value>10000</value>
 </parameter>

 <!-- MySQL dB username and password for dB connections -->
 <parameter>
 <name>username</name>
 <value>myuser</value>
 </parameter>

 <parameter>
 <name>password</name>
 <value>mypasswd</value>
 </parameter>

 <!-- Class name for mm.mysql JDBC driver -->

 <parameter>
 <name>driverClassName</name>
 <value>com.mysql.jdbc.Driver</value>
 </parameter>

 <!-- The JDBC connection url for connecting to MySQL dB.
 The autoReconnect=true argument to the url makes sure that the
 mm.mysql JDBC Driver will automatically reconnect if mysqld closed the
 connection. mysqld by default closes idle connections after 8 hours.
 -->

 <parameter>
 <name>url</name>
 <value>jdbc:mysql://10.10.10.11:3306/mydb?autoReconnect=true</value>
 </parameter>
 </ResourceParams>

 <!-- Description of the resource user transaction -->
  <Resource name="jdbc/tx" auth="Container" 
type="javax.transaction.UserTransaction" />

 <ResourceParams name="jdbc/tx">
 <parameter>
 <name>factory</name>
 <value>org.objectweb.jotm.UserTransactionFactory</value>
 </parameter>

 <parameter>
 <name>jotm.timeout</name>
 <value>60</value>
 </parameter>
 </ResourceParams>
 </Context>

 The method that starts the transaction looks as follows:

 public User addUserProfile(User newUser, User existingUser,
 UserDevice userDevice, UserRegistrationType regType)
 throws BOException {
 boolean success = false;

 try {
 userTx.begin();
 userBO.addUserProfile(newUser, existingUser, userDevice, regType);
 success = true;
 } catch (NotSupportedException nse) {
 logger.warn("Tx - operation not supported", nse);
 } catch (SystemException se) {
 logger.warn("Tx - system exception", se);
 } finally {
 try {
 if (success) {
 /*
 * Transaction was successful, commit it.
 */
 userTx.commit();
 } else {
 /*
 * Transaction failed, roll it back.
 */
 userTx.rollback();
 }
 } catch (Exception e) {
 // Report problem to the client
 success = false;
 }
 }

 return newUser;
 }

 The method that invokes the DAO layer:

  public void updateUserDeviceNumber(UserDevice userDevice, PhoneNumber 
number)
 throws BOException {
 try {
 getUserDeviceDAO().updatePhoneNumber(userDevice, number);
 } catch (DAOException daoe) {
 throw new BOException(daoe);
 }
 }

 The DAO method that throws the SQLException:

  public void updatePhoneNumber(UserDevice userDevice, PhoneNumber 
number)
 throws DAOException {

 Connection conn = null;
 PreparedStatement prepStmt = null;

 try {
 conn = MySQLDataStore.getInstance().getConnection();
 prepStmt = conn.prepareStatement(UPDATE_PHONE_NUMBER_STMT);

 prepStmt.setLong(1, number.getCountryCode());
 prepStmt.setLong(2, number.getAreaCode());
 prepStmt.setLong(3, number.getLocalNumber());
 prepStmt.setLong(4, userDevice.getId());

 prepStmt.execute();

 } catch (SQLException sqle) {
 logger.warn("Failed to update user phone number for device: "
 + userDevice.getId(), sqle);
 throw new DAOException(sqle);
 } finally {
 MySQLDataStore.getInstance().close(prepStmt, conn);
 prepStmt = null;
 conn = null;
 }
 }

 Connections are retrieved in the following way:

 public Connection getConnection() throws SQLException {
 if (primaryDS == null) {
 primaryDS = (DataSource) ctx.lookup(DataSourceNames.PRIMARY_DS);
 }
 return primaryDS.getConnection();
 }

 And the statement and connection are closed as follows:

 public void close(PreparedStatement ps, Connection conn) {
 if (ps != null) {
 try {
 ps.close();
 } catch (SQLException sqle) {
 avLogger.warn("Failed to close statement: " + ps, sqle);
 }
 }

 if (conn != null) {
 try {
 conn.close();
 } catch (Exception ex) {
 logger.debug(
 "Exception when closing connection: "
 + conn, ex);
 }
 }
 }

 ___________________________________________________
 Try the New Netscape Mail Today!
 Virtually Spam-Free | More Storage | Import Your Contact List
 http://mail.netscape.com

 ---------------------------------------------------------------------
 To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
 For additional commands, e-mail: users-help@tomcat.apache.org



___________________________________________________
Try the New Netscape Mail Today!
Virtually Spam-Free | More Storage | Import Your Contact List
http://mail.netscape.com


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org