Grails
  1. Grails
  2. GRAILS-7093

Better support to programmatic transactions (withTransaction closure extension/changing)

    Details

    • Type: Improvement Improvement
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: 2.4
    • Component/s: Persistence
    • Labels:
      None
    • Patch Submitted:
      Yes

      Description

      It's just a suggestion, but i really believe it would be a useful improvement:

      Apparently, withTransaction supports only propagation "required". This could be enough for regular applications, but it "fails" when you need a fine-grained transaction control.

      The suggested improvement is to offer another closure or to change withTransaction definition (HibernatePluginSupport.groovy) to support additional properties. These properties will be used to configure TransactionTemplate instance. I've written something similar in other project:

          def ctx = grailsApplication.mainContext
          grailsApplication.domainClasses.each {
            domainClass ->
      	domainClass.metaClass.static.withNewTransaction = {
      	  properties = [propagationBehavior: TransactionDefinition.PROPAGATION_REQUIRES_NEW],
      	  Closure callable ->
      	    def template = new TransactionTemplate(ctx.getBean('transactionManager'))
      	    properties.each {
      	      property ->
      		template[property.key] = property.value
      	    }
      	    template.execute({status ->
      	      callable.call(status)
      			     } as TransactionCallback)
              }
          }
      

      So we can easily start a new different transaction (even inside a Service class method/closure):

      MyDomainClass.withNewTransaction = {
         // Your code here
      }
      

      or explicitly:

      MyDomainClass.withNewTransaction(propagationBehavior: TransactionDefinition.PROPAGATION_REQUIRES_NEW) = {
         // Your code here
      }
      

      or even something more complex:

      MyDomainClass.withNewTransaction(propagationBehavior: TransactionDefinition.PROPAGATION_NESTED, isolationLevelName: 'ISOLATION_READ_UNCOMMITTED') = {
         // Your code here
      }
      

      It makes more sense to me to change withTransaction implementation than adding another closure because not every propagation type will create a "new transaction".

      For a new closure implementation, properties could be initialized as the sample (it's just a suggestion).
      For a changing in withTransaction implementation, properties should be initialized as an empty Map (properties = [:]) or null map (with null check), for backward compatibility.

      Reference:
      http://grails.org/doc/latest/ref/Domain%20Classes/withTransaction.html
      http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/transaction/TransactionDefinition.html#PROPAGATION_REQUIRED
      http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/transaction/support/TransactionTemplate.html

      Thanks!

        Issue Links

          Activity

          No work has yet been logged on this issue.

            People

            • Assignee:
              Jeff Scott Brown
              Reporter:
              Daniel Henrique Alves Lima
            • Votes:
              24 Vote for this issue
              Watchers:
              19 Start watching this issue

              Dates

              • Created:
                Updated:
                Last Reviewed:

                Development