Prevent Oracle Connection autocommit for JNDI Datasource on JBoss 7 (Jeeves DBMS)

6.6k views Asked by At

I am currently having an odd situation with the autocommit settings of an Oracle JNDI Datasource in JBoss 7.

The outline

The application I want to deploy, wich I can inspect but not change, obtains connections from the Connection Pool and trys to commit after certain statements. Obviously the connection has autocommit set to 'true' per default and so an exception is raised.

    You cannot commit with autocommit set!

What I cannot do

Due to the fact that I can't change the application source, the following "solution" is not applicable:

    con.setAutoCommit(false);

What I tried

I looked through the XML Schema of the standalone.xml and found two promising elements in the datasource definition:

    <connection-property name="autoCommit">
     false
    </connection-property>

but this is being ignored.

Further I tried using a xa-datasource with the following property:

    <xa-datasource-property name="autoCommit">
     false
    </xa-datasource-property>

but the autoCommit property belongs to the connection, not the datasource, so a PropertyNotFound Exception is raised.

My question

How can I set Autocommit to false in a JNDI Datasource under JBoss7 and am I missing something?

My definition

<datasource jta="false" jndi-name="java:/*****" pool-name="*****" enabled="true">
    <connection-url>jdbc:oracle:thin:@****:****:****</connection-url>
    <connection-property name="autoCommit">
        false
    </connection-property>
    <driver>oracle.jdbc</driver>
    <pool>
        <min-pool-size>10</min-pool-size>
        <max-pool-size>100</max-pool-size>
        <prefill>true</prefill>
        <use-strict-min>false</use-strict-min>
        <flush-strategy>FailingConnectionOnly</flush-strategy>
    </pool>
        <security>
        <user-name>*****</user-name>
        <password>*****</password>
    </security>
    <timeout>
        <blocking-timeout-millis>5000</blocking-timeout-millis>
        <idle-timeout-minutes>1</idle-timeout-minutes>
    </timeout>
</datasource>

Update

Code Snippet:

      public AccessManager(jeeves.resources.dbms.Dbms dbms, SettingManager sm)
        throws SQLException
      {
        List operList = dbms.select("SELECT * FROM Operations").getChildren();          
      }

Update 2

The Application I want to deploy is the Geonetwork CSW 2.9.0, just in case someone has experience with this. I have to configure a JNDI datasource because the spatial indexing only happens on container managed connections.

Update 3

Stacktrace:

    15:52:18,203 ERROR [jeeves.engine] (MSC service thread 1-4) Raised exception while starting appl handler. Skipped.
    15:52:18,205 ERROR [jeeves.engine] (MSC service thread 1-4)    Handler   : org.fao.geonet.Geonetwork
    15:52:18,206 ERROR [jeeves.engine] (MSC service thread 1-4)    Exception : java.sql.SQLException: You cannot commit with autocommit set!
    15:52:18,210 ERROR [jeeves.engine] (MSC service thread 1-4)    Message   : You cannot commit with autocommit set!
    15:52:18,213 ERROR [jeeves.engine] (MSC service thread 1-4)    Stack     : java.sql.SQLException: You cannot commit with autocommit set!
            at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.jdbcCommit(BaseWrapperManagedConnection.java:984)
            at org.jboss.jca.adapters.jdbc.WrappedConnection.commit(WrappedConnection.java:757)
            at jeeves.resources.dbms.Dbms.commit(Dbms.java:150)
            at jeeves.resources.dbms.AbstractDbmsPool.close(AbstractDbmsPool.java:158)
            at jeeves.server.resources.ResourceManager.release(ResourceManager.java:302)
            at jeeves.server.resources.ResourceManager.close(ResourceManager.java:270)
            at jeeves.server.JeevesEngine.initAppHandler(JeevesEngine.java:556)
            at jeeves.server.JeevesEngine.init(JeevesEngine.java:182)
            at jeeves.server.sources.http.JeevesServlet.init(JeevesServlet.java:87)
            at javax.servlet.GenericServlet.init(GenericServlet.java:242)
            at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1202)
            at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1102)
            at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3655)
            at org.apache.catalina.core.StandardContext.start(StandardContext.java:3873)
            at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:90)
            at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
            at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
            at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
            at java.lang.Thread.run(Thread.java:662)

Update 4

Just realized that the Jeeves DBMS is a simple wrapper around the JNDI Datasource that obtains connections just like anyone would do with plain JDBC. So I am back at the beginning.

1

There are 1 answers

3
JSniffer On BEST ANSWER

Thanks for giving me directions, found a solution (Correction: Workaround) that suits me well. I made a wrapper around the original datasource, overrid the getConnection() Method and bound it under a new JNDI Name. This way I have full control over the datasource without losing any functionality from the container.