-
Notifications
You must be signed in to change notification settings - Fork 1
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
Add support for confounding variables #877
Add support for confounding variables #877
Conversation
As confounding variables are valid for all samples in an experiment (including samples where a value might not yet been known), I decided to go for including empty variables in the samples. |
|
> The Spring team recommends that you annotate methods of concrete classes with the @transactional annotation, rather than relying on annotated methods in interfaces, even if the latter does work for interface-based and target-class proxies as of 5.0. https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/annotations.html
…etadata-to-add-confounding-variables # Conflicts: # user-interface/src/main/bundles/dev.bundle
…etadata-to-add-confounding-variables
…etadata-to-add-confounding-variables
…etadata-to-add-confounding-variables # Conflicts: # user-interface/src/main/bundles/dev.bundle
…etadata-to-add-confounding-variables
For this to work, sql/complete-schema.sql has to be executed on the database |
@KochTobi there are some conflicts with the target branch |
@KochTobi can you elaborate more on the changes in the database? I also encourage to look into database versioning solutions like Flyway. I have some concerns with our current database schema development strategy: hoping for the best and no way back. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor change requests, but I have some concerns with how we deal with database changes.
...-management/src/main/java/life/qbic/projectmanagement/application/sample/SampleMetadata.java
Outdated
Show resolved
Hide resolved
throws RegistrationException { | ||
var result = batchRegistrationService.registerBatch(batchLabel, batchIsPilot, projectId, | ||
experimentId); | ||
ExperimentId.parse(experiment.id())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we overdid it here big time with the Identifier... Imo there is no need to parse, because it does not have any semantics or schema. It is just a string value generated from the UUID generator. You either find an object with the ID in the database, or you dont.
Happy to see some simplification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree!
} | ||
|
||
@PreAuthorize("hasPermission(#projectId, 'life.qbic.projectmanagement.domain.model.project.Project', 'WRITE')") | ||
@Async | ||
@Transactional(propagation = Propagation.REQUIRES_NEW) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this annotation do? Why is it needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The transactional annotation is needed to indicate a transaction taking place. It starts a transaction in the database and commits changes when exiting the method. The propagation property tells spring that a new transaction is to be created for this operation. The default behaviour is that an existing active transaction is used and if there is none that one is created. I do not think we need to create a new transaction here so I removed the propagation type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this guarantees the transactional scope of the method? I am not sure, if I get it. Can you explain with an example, what would happen without it and what undesired side effects it has?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are different scenarios:
- no
@Transactional
annotation - a
@Transactional
annotation withoutPropagation.REQUIRES_NEW
- a
@Transactional
annotation the default propagation
in 1. there will be an exception if the method is called from outside a transactional context. In our case no transactional context exists so the exception will be thrown. Without any transaction, no rollback is possible
in 2. at the start of the method a new transaction will be created, suspending an existing transaction if any already exists in this scope. The changes are made within the new transaction which is committed when the method exits (or rolled back in case of exceptions). After the newly created transaction finishes (commit or rollback) the previously suspended transaction continues.
in 3. when called from a transactional scope (already existing transaction) the operations within the method are appended/added to the existing transaction. If the method throws an exception the complete transaction (including the changes made before this method was called) are rolled back. If no transaction existed when the method is called, a new transaction is created.
The difference between 2. and 3. is that in 2. a transaction is suspended. Rollbacks do not affect a scope outside of the method in 2. Suspending transactions bears a risk of deadlocking the system. If the amount of maximal transactions is limited and the creation of the transaction fails, there might be a scenario where the original transaction is kept in a suspended state further limiting the amount of available transactions.
We also want to rollback an existing transaction in case of exceptions so only rolling back changes made in this method is not what we want I think.
Thus the propagation type of REQUIRES_NEW
was wrong here.
Further information: https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/annotations.html
...rc/main/java/life/qbic/projectmanagement/application/sample/SampleRegistrationServiceV2.java
Outdated
Show resolved
Hide resolved
...rc/main/java/life/qbic/projectmanagement/application/sample/SampleRegistrationServiceV2.java
Outdated
Show resolved
Hide resolved
…etadata-to-add-confounding-variables # Conflicts: # user-interface/src/main/bundles/dev.bundle # user-interface/src/main/java/life/qbic/datamanager/templates/sample/SampleBatchUpdateTemplate.java
Yes I resolved it. |
Hi Sven. I simply merged all the sql files to set up the database into one and added the tables for confounding variables. In this case the database schema is simply extended by the tables of confounding variables (samples, experiment and so forth are not touched). Even thou the topic of database migration and future proofing is of great importance, I would like to separate the investigation on database migration and future proofing from this PR. |
Co-authored-by: Sven F. <[email protected]>
I don't think we need a new transaction when creating samples Co-authored-by: Sven F. <[email protected]>
…etadata-to-add-confounding-variables
Co-authored-by: Sven F. <[email protected]>
Co-authored-by: Sven F. <[email protected]>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @KochTobi, i am looking forward to the users feedback!
#1000 <- to track the need |
Addresses #642