-
Notifications
You must be signed in to change notification settings - Fork 952
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Grails 3.1 Transactional Behavior & Documentation Appear Incorrect #9785
Comments
Will be sending pull request following discussion with @jeffbrown using the logic as
|
I think the logic quoted above is reasonable. Feedback is welcome. |
I think the proposed change...
...will yield the wrong behavior. I think that will create the proxy when the annotation is present. |
Yeah that is wrong. Understanding how the static property and annotation work has cleared that up. |
Just to restate what was described in Slack, I think the only issue here is the config property name and its default value. Is that correct? |
Yes, two line change minus tests. |
I am wondering if we should leave the default config property value as is for 3.1.x and only change it for 3.2 since it is a real change in behavior that could be problematic. |
I would like @graemerocher's input before we merge any PRs. He is on vacation this week. |
I can pull against master in that case. I can PR again against 3.1.x later. |
I think that is fine. If you make it behave as described in the logic you quoted above and make that into a PR against master, then we can take it from there. Thanks for all of the help. |
The code change was easy... the tests are proving to be a !@#$. |
It is actually the datasourceName in the DefaultGrailsServiceClass that is causing some issues when calling getDatasource that is proving difficult. |
Is that relevant to the transactional behavior and the docs being out of sync? |
I have a work around but the data source method used to work one way when the static property for transactional was null or true. Now if we only detect true it changes the behavior of the ultimate name of the datasource. It would be bad for to inspect annotations in core so I will have to reevaluate and perhaps set transactional during service wiring when annotations present and proxy intended. Will post code here in a bit. |
Given the attachment of the datasource name to the service artifact, and it's apparent dependency to knowing the transactionality of the service, even if removing the static property this will probably be necessary. |
I probably need to digest how the datasource, the service artifact and transactions all play together a bit more. |
The logic that I landed on is as follows
|
I think that would mean that if |
We have observed in 3.1.0 when setting |
Even if you wanted it to prevent proxies for classes marked with |
Is the proposal to remove (or maybe just not to add) the annotation driven transaction management post processor stuff if the config setting is set to false? |
I didn't run through the full spring wiring scenario but the code in the PR will skip wiring the TypeSpecifyableTransactionProxyFactoryBean if the comfig property is set to false. It would appear, based on the tests, that this works on the surface. But I defer to you, having more experience in spring code than I, if that isn't sufficient. |
I don't think skipping the wiring of a |
I think it might work if we omitted adding the post processor but I am not sure that is the right thing. Maybe it is. My thinking is that if the author of a class explicitly marks a class with |
I think the best course is the simplest and to adjust the config value to simply toggle the support for the static property. |
Will update PR tomorrow am. |
The code at Line 56 in 57df0a1
That appears to be written with the intent of not registering the annotation driven transaction manager contraption if the config setting is set to false. I think that ignoring the Spring annotation altogether when the config setting is false is potentially problematic. Maybe I am the minority with that concern though. |
An issue I see is that as the author of a plugin I may be explicit in saying I want the Spring proxy. I do that by using the Spring annotation. If that plugin is used in an app that sets the proxy setting to false, bad things could happen. So far I think I am outnumbered though. |
The more I think about this, I am backing away from my own position above. I think the intent may be to disable the proxying altogether when setting the config setting to |
We no longer use any spring annotations in favor of the grails annotation and disabling the default transactionality via the config flag has given us a HUGE boost in performance. I will defer this issue to you and your minions, but wanted to throw that out there. |
That all makes sense to me. |
The current documentation for grails 3.1.x states that transactions are
disabled
by default for services and can be enabled usinggrails.spring.transactionManagement: true
in yaml. However the property appears to actually begrails.spring.transactionManagement.proxies
AND it appears to be true by default as seen here https://github.com/grails/grails-core/search?utf8=%E2%9C%93&q=SPRING_TRANSACTION_MANAGEMENTWe were able to get the default for transactions to be off by setting
grails.spring.transactionManagement.proxies: false
in our yaml. After doing this we were seeing the correct number of transactions only for those methods annotated with @transactional.Note the incorrect property setting here https://grails.github.io/grails-doc/latest/guide/services.html
Line where property is defaulting for all services to true:
grails-core/grails-plugin-services/src/main/groovy/org/grails/plugins/services/ServicesGrailsPlugin.groovy
Line 56 in 623d575
This appears to go back to DefaultGrailsServiceClass.java where a service with no annotation or
static transactional
is being wired as transactional true due totransactional = tmpTransactional == null
then
springTransactionManagement
is defaulting to true viaconfig.getProperty(Settings.SPRING_TRANSACTION_MANAGEMENT, Boolean.class, true)
Then the logic fires at
shouldCreateTransactionalProxy
and the evaluation for the logical condition returns true because all these evaluate to true where ALL services with no static transactional areserviceClass.transactional = true
have no annotation!AnnotationUtils.findAnnotation(javaClass, grails.transaction.Transactional) = true
have no spring annotation!AnnotationUtils.findAnnotation(javaClass, Transactional) = true
and no method has spring of grails transactional!javaClass.methods.any { Method m -> AnnotationUtils.findAnnotation(m, Transactional) != null || AnnotationUtils.findAnnotation(m, grails.transaction.Transactional) != null} = true
This is the existing block:
Due to how it checks for transactions simply using
grails.spring.transactionManagement.proxies: false
works, however this is incorrect in the documentation and the default value is currently true for this value when not provided.Newly generated projects come ouf the gate with
but this doesn't actually appear to affect the transactional behavior.
The text was updated successfully, but these errors were encountered: