Results 1 to 9 of 9

Thread: When using JdbcTemplate, how do I access the connection?

  1. #1
    Join Date
    Aug 2004
    Posts
    6

    Default When using JdbcTemplate, how do I access the connection?

    In an EJB app, I'm using JdbcTemplate to simplify some of the SQL coding
    I must do. Basically, I've got a session bean which uses JdbcTemplate, and
    the datasource that the session bean uses is an XA datasource which
    defaults to auto-commit off.

    For various reasons, I need to turn auto-commit on in the connection that
    JdbcTemplate ends up using, and possibly invoke commit or rollback on
    the connection as well, presumably prior to closing the connection.

    How can I gain access to the connection that JdbcTemplate uses?

    Thanks!

    : jay

  2. #2
    Join Date
    Aug 2004
    Posts
    1,104

    Default

    Short answer - you should not mess with the connection. Use some kind of transaction management that is available for your application server. You can use Bean Managed transactions if you want and you can also use Spring's transaction framework to demarcate your transactions. I can't see any good reasons for manipulating the connection in an EJB environment.

    Here is an example of a transaction setup where the methods in the target class are all executed within a new transaction.

    Code:
    <!--  transaction manager -->
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
      <property name="transactionManagerName">
        <value>javax.transaction.TransactionManager</value>
      </property>
    </bean>
    
    <!-- factory bean with all methods executed in new transaction. -->
    <bean id="senderNewTx" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
      <property name="transactionManager">
      </property>
      <property name="target">
        <bean class="org.buggybean.MyTargetClass"/>
      </property>
      <property name="transactionAttributes">
        <props>
          <prop key="*">PROPAGATION_REQUIRES_NEW</prop>
        </props>
      </property>
    </bean>
    Having said that, if you really need the Connection you can use
    Code:
    jdbcTemplate.getDataSource&#40;&#41;.getConnection&#40;&#41;
    to get hold of the COnnection object.
    Thomas Risberg
    SpringSource by Pivotal
    http://www.springsource.org

  3. #3
    Join Date
    Aug 2004
    Location
    Montréal, Canada
    Posts
    845

    Default

    jdbcTemplate.getDataSource().getConnection()
    I have a small question with regards to this: Does jdbcTemplate use the same connection?
    I mean, if I call getDataSource().getConnection() twice in my jdbcTemplate, am I garanteed to get the same connecition?
    Omar Irbouh

    Spring Modules Team
    http://irbouh.blogspot.com/

  4. #4
    Join Date
    Aug 2004
    Posts
    6

    Default

    We are using WebLogic 8.1 as our appserver. We are using distributed
    transactions as our app uses both Informix and Oracle. We are runnning
    into a situation where we receive the following exceptionr:

    java.sql.SQLException: SQL operations are not allowed with no global
    transaction by default for XA drivers. If the XA driver supports performing
    SQL operations with no global transaction, explicitly allow it by setting
    "SupportsLocalTransaction" JDBC connection pool property to true. In this
    case, also remember to complete the local transaction before using the
    connection again for global transaction, else a XAER_OUTSIDE
    XAException may result. To complete a local transaction, you can either
    set auto commit to true or call Connection.commit() or Connection.rollback().

    The basic scenario is client makes a remote method call on a session bean
    A. Bean A then makes a local method call on session bean B. B makes use
    of JdbcTemplate to do some read-only JDBC things and returns the results
    to A. A then goes on to retrieve some entity beans and possibly update
    them.

    It seemed plausible to me that perhaps the local transaction was being
    started because of the read-only JDBC operations, and so acquiring the
    connection from JdbcTemplate and invoking commit or rollback on it
    might solve the problem. Hence the original question.

    However jdbcTemplate.getDataSource().getConnection() will give me a
    brand new connection, won't it? I'll need the connection used to by
    JdbcTemplate to perform the query in order to do a commit or rollback
    on it.

    : jay

  5. #5
    Join Date
    Aug 2004
    Posts
    1,104

    Default

    Sounds like you are trying to operate outside of a global transaction. Have you tried setting B's transaction property to NotSupported and then use a non-XA JDBC driver?

    If you want to be sure to use the same connection for some processing then you can create a SingleConnectionDataSource like this:
    Code:
    		Connection singleConn = dataSource.getConnection&#40;&#41;;
    		singleConn.setAutoCommit&#40;true&#41;;
    		SingleConnectionDataSource singleDs = new SingleConnectionDataSource&#40;singleConn, true&#41;;
    		JdbcTemplate jt2 = new JdbcTemplate&#40;singleDs&#41;;
    		Number n = &#40;Number&#41; jt2.queryForObject&#40;"select count&#40;*&#41; from booking", Number.class&#41;; 
    		singleDs.destroy&#40;&#41;;
    You need to call destroy() to properly return the connection to the pool.
    Thomas Risberg
    SpringSource by Pivotal
    http://www.springsource.org

  6. #6
    Join Date
    Aug 2004
    Location
    St. Louis, MO
    Posts
    39

    Default

    Also, silly question but you didn't mention it....you are using the JTA transactionManager in your spring configuration, correct?

  7. #7
    Join Date
    Aug 2004
    Location
    Toronto, Canada
    Posts
    736

    Default

    Quote Originally Posted by irbouho
    jdbcTemplate.getDataSource().getConnection()
    I have a small question with regards to this: Does jdbcTemplate use the same connection?
    I mean, if I call getDataSource().getConnection() twice in my jdbcTemplate, am I garanteed to get the same connecition?
    That's a good question. No, you would actually get another connection, unless the DataSource itself is some sort of special DS (like the test one) which always returns the same connection. And you would in fact be responsible for properly closing that connection. If you want to just reuse the connection that may already be bound to the thread, and ensure that if there is none already bound there a new one is created and bound, you should actually use:

    Connection con = DataSourceUtils.getConnection(myJdbcTemplate.getDa taSource());

    That's basically what JdbcTemplate does itself, internally. Any connection you get like this will also properly be closed by the template itself (if you are using it inside the template in an execute callback) or the enclosing transaction, depending on where the connection is actually synchronized.

    Regards,
    Colin Sampaleanu
    SpringSource - http://www.springsource.com

  8. #8
    Join Date
    Aug 2004
    Posts
    6

    Default

    Quote Originally Posted by ryan.tyer
    Also, silly question but you didn't mention it....you are using the JTA transactionManager in your spring configuration, correct?
    No, that's not a silly question. I have no spring configuration other than its
    default. I started using Spring because I had started going down the path
    of developing something very much like JdbcTemplate, and then stumbled
    across Spring and began using its JDBC support because it did almost
    everything I needed, and it seemed to work "out-of-the-box".

    Should I be using the JTA transaction manager? Judging by its name, I
    think so. How do I configure it? To this point, I've really made use of very
    little of Spring other than JdbcTemplate.

    : jay

  9. #9
    Join Date
    Sep 2004
    Location
    Szeged, Hungary
    Posts
    7

    Default

    Quote Originally Posted by trisberg
    Code:
    <!--  transaction manager -->
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
      <property name="transactionManagerName">
        <value>javax.transaction.TransactionManager</value>
      </property>
    </bean>
    I think there is some typo here... transactionManagerName property expects the JNDI name of the TM of the given container... no?

    Code:
    <!--  transaction manager -->
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
      <property name="transactionManagerName">
        <value>java&#58;/TransactionManager</value>
      </property>
    </bean>
    on JBoss, and see Spring JavaDoc JtaTransactionManager for other containers.

    Bye,
    cstamas

Similar Threads

  1. Connection closed after transaction commit
    By alirussi in forum Data
    Replies: 4
    Last Post: Dec 17th, 2011, 06:41 AM
  2. Replies: 2
    Last Post: Jul 8th, 2005, 10:37 PM
  3. Replies: 15
    Last Post: Jun 3rd, 2005, 08:19 AM
  4. CMT, JdbcTemplate and connection pools
    By jayschm in forum EJB
    Replies: 3
    Last Post: Apr 25th, 2005, 08:11 AM
  5. Replies: 0
    Last Post: Apr 6th, 2005, 08:24 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •