OracleDataSource vs. Oracle UCP PoolDataSource

后端 未结 8 1844
无人共我
无人共我 2020-12-02 10:24

I was researching some JDBC Oracle Connection Pooling items and came across a new(er) Oracle Pool implementation called Universal Connection Pool (UCP). Now this uses a new

相关标签:
8条回答
  • There are two possible ways to use UCP in Spring Bean.xml.

    For db.properties set by some file then load this then Use one of them:

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    
        <property name="location">
            <value>classpath:resources/db.properties</value>
        </property>
    </bean>
    

    First one wiht oracle.ucp.jdbc.PoolDataSourceImpl :-

    <bean id="dataSource" class="oracle.ucp.jdbc.PoolDataSourceImpl">
    
        <property name="URL" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    
        <property name="validateConnectionOnBorrow" value="true"/>
    
        <property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource" />
        <property name="connectionPoolName" value="TEST_POOL" />
        <property name="minPoolSize" value="10" />
        <property name="maxPoolSize" value="20" />
        <property name="initialPoolSize" value="12" />
    </bean>
    

    Second one with oracle.ucp.jdbc.PoolDataSourceFactory :-

     <bean id="dataSource" class="oracle.ucp.jdbc.PoolDataSourceFactory"  
         factory-method="getPoolDataSource">        
        <property name="URL" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    
        <property name="validateConnectionOnBorrow" value="true"/>
    
        <property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource" />
        <property name="connectionPoolName" value="TEST_POOL" />
        <property name="minPoolSize" value="10" />
        <property name="maxPoolSize" value="20" />
        <property name="initialPoolSize" value="12" />
    </bean>
    

    That's It :) Here is the link for Detail Documentation : https://docs.oracle.com/cd/E11882_01/java.112/e12265/connect.htm#CHDDCICA

    0 讨论(0)
  • 2020-12-02 10:27

    I did an extensive evaluation of UCP and decided to NOT use UCP - please have a look at this post for details.

    0 讨论(0)
  • 2020-12-02 10:29

    I tried ucp and the performance is better... May be the key is using this

    oracle.ucp.jdbc.PoolDataSource ds = (oracle.ucp.jdbc.PoolDataSource)envContext.lookup(url_r);
    MyConnectionLabelingCallback callback = new MyConnectionLabelingCallback();
    ds.registerConnectionLabelingCallback( callback );
    
    
    Properties label = new Properties();
    label.setProperty(pname, KEY);
    conn = ds.getConnection(label);
    

    This helps to borrow the connection and never closing it.. so the performance is great

    The code for the callback class is

    public class MyConnectionLabelingCallback
    implements ConnectionLabelingCallback {
    
          public MyConnectionLabelingCallback()
          {
          }
    
          public int cost(Properties reqLabels, Properties currentLabels)
          {
    
            // Case 1: exact match
            if (reqLabels.equals(currentLabels))
            {
              System.out.println("## Exact match found!! ##");
              return 0;
            }
    
            // Case 2: some labels match with no unmatched labels
            String iso1 = (String) reqLabels.get("TRANSACTION_ISOLATION");
            String iso2 = (String) currentLabels.get("TRANSACTION_ISOLATION");
            boolean match =
              (iso1 != null && iso2 != null && iso1.equalsIgnoreCase(iso2));
            Set rKeys = reqLabels.keySet();
            Set cKeys = currentLabels.keySet();
            if (match && rKeys.containsAll(cKeys))
            {
              System.out.println("## Partial match found!! ##");
              return 10;
            }
    
            // No label matches to application's preference.
            // Do not choose this connection.
            System.out.println("## No match found!! ##");
            return Integer.MAX_VALUE;
          }
    
          public boolean configure(Properties reqLabels, Object conn)
          {
    
              System.out.println("Configure################");
            try
            {
              String isoStr = (String) reqLabels.get("TRANSACTION_ISOLATION");
              ((Connection)conn).setTransactionIsolation(Integer.valueOf(isoStr));
              LabelableConnection lconn = (LabelableConnection) conn;
    
              // Find the unmatched labels on this connection
              Properties unmatchedLabels =
               lconn.getUnmatchedConnectionLabels(reqLabels);
    
              // Apply each label <key,value> in unmatchedLabels to conn
              for (Map.Entry<Object, Object> label : unmatchedLabels.entrySet())
              {
                String key = (String) label.getKey();
                String value = (String) label.getValue();
                lconn.applyConnectionLabel(key, value);
              }
            }
            catch (Exception exc)
            {
    
              return false;
            }
            return true;
          }
        }
    
    0 讨论(0)
  • 2020-12-02 10:31

    I tested the UCP and deployed it to production in a Spring 3.0.5 Hibernate app using Spring JMS listener containers and Spring-managed sessions and transactions using the @Transactional annotation. The data sometimes causes SQL constraint errors, due to separate listener threads trying to update the same record. When that happens, the exception is thrown by one method annotated by @Transactional and the error is logged into the database using another method annotated by @Transactional. For whatever reason, this process seems to result in a cursor leak, that eventually adds up and triggers the ORA-01000 open cursor limit exceeded error, causing the thread to cease processing anything.

    OracleDataSource running in the same code doesn't seem to leak cursors, so it doesn't cause this problem.

    This is a pretty weird scenario, but it indicates to me that it's a little too early to be using the UCP in an application with this kind of structure.

    0 讨论(0)
  • 2020-12-02 10:41

    PDS is 'universal' as it provides the same level of pooling functionality you get in ODS for non-Oracle databases, e.g. MySQL.

    See UCP Dev Guide, an article on Oracle website and UCP Transition Guide

    I don't see any immediate benefit of moving to UCP (PDS) from ODS, but perhaps in the future Oracle will deprecate some of the functionality in ODS. I used ODS for a while and I'm quite happy with it for the time being, but if I started fresh I'd go with PDS.

    0 讨论(0)
  • 2020-12-02 10:42

    I too am testing UCP and am finding myself that I am having performance issues in a Thread Pool based application. Initially, I tried OracleDataSource, but am having trouble configuring it for batch processing. I keep getting NullPointerExceptions in the connections, leading me to believe I have some sort connection leak, but only with some application, there are other applications we manage that are not batch process oriented that OracleDataSource works well.

    Based on this post and a few others I found researching this subject, I tried UCP. I found that with enough tweaking, I could get rid of closed connections/NullPointerExceptions on connections style errors, but Garbage Collection was taking a beating. Long-Term GC fills up fast and does not ever seem to free up until the application finishes running. This can sometimes take as long as a day or more if the load is really heavy. I also notice that it takes progressive longer to process data as well. I compare that to the now depreciated OracleCacheImpl class (that we currently use in production because it still "just works"), where it used a third of the GC memory that UCP does and processes files much faster. In all other applications UCP seems to work just fine and handles just about everything I throw at it, but the Thread Pool Application is a major app and I could not risk GC Exceptions in production.

    0 讨论(0)
提交回复
热议问题