7 Replies Latest reply on Jul 24, 2007 2:31 PM by adrian.brock

    Allow setAutoCommit(false) on managed connections

    dimitris

      This was raised as a JIRA feature request on EAP, so I'm copying the request here. I'm not sure yet what the proper workflow would be, i.e. where EAP issues should be discussed, before JIRAs are opened against the corresponding projects (i.e. AS in this case).


      Invoking setAutoCommit(false) on a managed connection should simply be ignored instead of rising an exception.

      It is not a sensible thing to do, of course, but some frameworks do this.
      It would be nice to have this feature, making JBoss more flexible and tolerant towards 3rd party software that has this deficiency.


      http://jira.jboss.com/jira/browse/JBPAPP-243

        • 1. Re: Allow setAutoCommit(false) on managed connections

          That would be in violation of the spec. JavaEE5 EE.6.2.4.2



          The component
          should not attempt to change the transaction characteristics of the connection,
          commit the transaction, roll back the transaction, or set autocommit mode.
          Attempts to make changes that are incompatible with the current transaction
          context may result in a SQLException being thrown. The EJB speci?cation
          contains the precise rules for enterprise beans.


          It would also break the semantics of the code:
          Connection c = dataSource.getConnection();
          try
          {
           c.setAutoCommit(false);
           // do multiple operations
          }
          finally
          {
           if (errorOccurred)
           c.rollback();
           else
           {
           c.commit();
           // HERE WE KNOW THE WORK WAS DONE
           }
          }
          


          The proposed change would mean we need to ignore the c.commit() as well
          (the JTA transaction handles it)
          so the assumption in the above code is broken.

          I suspect what you really asking for is a piece of configuration
          that already exists. i.e. use a no-tx-datasource
          such that the code controls the transaction and not the appserver.

          Or use NOT_SUPPORTED transaction demarcation (so the
          connection is not enlisted in a JTA transaction - there isn't one).

          i.e. You have a misunderstanding about what the real requirements are.

          • 2. Re: Allow setAutoCommit(false) on managed connections
            bill.burke

            Adrian, you're sounding too much like Mark Little.

            setAutomCommit(false); does not change the transactional characteristics of the connection because autoCommit is already false. There is no state change with the call. Since there is no state change, then no error should be thrown. So you can ignore a setAutoCommit(false) with no repurcutions.

            The problem the user is having is that he wants to invoke thirdparty code that he cannot control, with a JTA/JCA managed connection within a transaction. Because of your interpretation of the spec, he cannot do this.

            • 3. Re: Allow setAutoCommit(false) on managed connections

               

              "bill.burke@jboss.com" wrote:
              Adrian, you're sounding too much like Mark Little


              That's a complement :-)


              setAutomCommit(false); does not change the transactional characteristics of the connection because autoCommit is already false.


              We're not talking about the state of the connection, we're talking about when the
              commit occurs. Is it, where my code assumes it is in the example I posted above
              or is in the JTA transaction demarcation after the method ends (breaking my code!).

              By breaking my code, I mean I start another transaction on the connection
              or I do something else that requires the transaction committed succesfully.

              The problem the user is having is that he wants to invoke thirdparty code that he cannot control, with a JTA/JCA managed connection within a transaction.
              


              This is broken. I'm not going to break other people's code to make this work
              (or more likely lead them to make the same mistakes).

              It will also lead to non-portable code. Other appservers won't run it.

              If you want to introduce a ManagedConnectionFactory property that does
              setIgnoreAutoCommitInManagedConnection(true);
              

              then go ahead. But it needs to be false by default and come with a big
              health warning about setting it to true.

              • 4. Re: Allow setAutoCommit(false) on managed connections
                bill.burke

                I don't think you are listening to me. connection.commit() /rollback()SHOULD fail as it is a state change. setAutoCommit(false) should succeed as there is no state change to the connection if auto commit is already false.

                Thirdparty code may not be doing commit(), rollback(), but may only be doing setAutoCommit(false). Which should be perfectly fine, again, because there is no state change to the connection. This could be what the user is running into. I don't know.

                Weston/myself had similar spec religiousness debates with Mark Little around allowing multiple non-XA resources in a transaction.

                Morale of the story? You may know something is wrong and not the right way to do it, but there may be no other way because you don't control all the variables.

                Anyways, since I am not coding any of this, doesn't really matter what I think....

                • 5. Re: Allow setAutoCommit(false) on managed connections

                   

                  "bill.burke@jboss.com" wrote:
                  I don't think you are listening to me. connection.commit() /rollback()SHOULD fail as it is a state change. setAutoCommit(false) should succeed as there is no state change to the connection if auto commit is already false.

                  Thirdparty code may not be doing commit(), rollback(), but may only be doing setAutoCommit(false). Which should be perfectly fine, again, because there is no state change to the connection. This could be what the user is running into. I don't know.


                  Impossible. The code would never work without a commit() outside a JTA transaction.
                  connection.close() does a rollback if there was no commit.


                  Weston/myself had similar spec religiousness debates with Mark Little around allowing multiple non-XA resources in a transaction.

                  Morale of the story? You may know something is wrong and not the right way to do it, but there may be no other way because you don't control all the variables.


                  But using non-XA resources works in most cases (there are some failures
                  that don't).

                  What's important is that it doesn't break code using XA resources to support it.

                  There's absolutely no way
                  Connection c = datasource.getConnection();
                  try
                  {
                   c.setAutoCommit(false)
                   // do stuff but don't commit
                  }
                  finally
                  {
                   c.close();
                  }
                  


                  works in any environment. It's just broken code.

                  • 6. Re: Allow setAutoCommit(false) on managed connections
                    bill.burke

                    What if the connection is being passed as a parameter and committed/rolledback/closed outside of this method?

                    • 7. Re: Allow setAutoCommit(false) on managed connections

                      I doubt that method fails to commit either (and if it crosses an
                      EJB/transaction boundary it is even more broken :-).

                      But this is beside the point. The rules are simple.
                      If you want it, you do it!
                      As long as it is disabled by default.

                      I could have done it in the time it took for this
                      argument if I thought it was a good thing
                      (my guess is that it doesn't even solve the problem!)

                      BUT ONLY DO IT IF YOU ARE WILLING TO SUPPORT IT AND
                      ANSWER ALL THE STUPID QUESTIONS.

                      I'm fed up of people adding unsupportable/broken features and leaving others
                      to answer the faqs with the same old message;

                      "Don't use it is broken and its an anti-pattern/anti-spec."

                      The classic example is remote datasource usage - http://jira.jboss.com/jira/browse/JBAS-1794
                      which is an issue that goes back long before I opened that JIRA issue 2 years ago.

                      If I thought it was a good feature, I'd have fixed it. I don't, so I won't. :-)
                      Well actually, I probably will eventually (since nobody else is stepping up to the plate)
                      but its nowhere near the top of my priorities.