Skip to content
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

Fix potential Invalid state. Transaction has already started in RepositoryMetaAnalyzerTask #2678

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/main/java/org/dependencytrack/persistence/QueryManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -1315,6 +1315,23 @@ public void runInTransaction(final Runnable runnable) {
}
}

/**
* Convenience method to ensure that any active transaction is rolled back.
* <p>
* Calling this method may sometimes be necessary due to {@link AlpineQueryManager#persist(Object)}
* no performing a rollback in case committing the transaction fails. This can impact other persistence
* operations performed in the same session (e.g. {@code NucleusTransactionException: Invalid state. Transaction has already started}).
*
* @see <a href="https://github.com/DependencyTrack/dependency-track/issues/2677">Issue 2677</a>
* @since 4.8.0
*/
public void ensureNoActiveTransaction() {
final Transaction trx = pm.currentTransaction();
if (trx != null && trx.isActive()) {
trx.rollback();
}
}

public void recursivelyDeleteTeam(Team team) {
pm.setProperty("datanucleus.query.sql.allowAll", true);
final Transaction trx = pm.currentTransaction();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,9 @@ public class RepositoryMetaAnalyzerTask implements Subscriber {
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
public void inform(final Event e) {
if (e instanceof RepositoryMetaEvent) {
if (e instanceof final RepositoryMetaEvent event) {
LOGGER.debug("Analyzing component repository metadata");
final RepositoryMetaEvent event = (RepositoryMetaEvent)e;
// TODO - Remove when https://github.com/DependencyTrack/dependency-track/issues/2110 is implemented
Timer timer = Timer.builder("repository_meta_analyzer_task")
.description("Repository meta analyzer task timer")
Expand All @@ -89,6 +87,7 @@ public void inform(final Event e) {
// Refreshing the object by querying for it again is preventative
LOGGER.info("Performing component repository metadata analysis against " + components.size() + " components");
for (final Component component: components) {
qm.ensureNoActiveTransaction(); // Workaround for https://github.com/DependencyTrack/dependency-track/issues/2677
analyze(qm, qm.getObjectById(Component.class, component.getId()));
}
LOGGER.info("Completed component repository metadata analysis against " + components.size() + " components");
Expand All @@ -101,6 +100,7 @@ public void inform(final Event e) {
final List<Component> components = qm.getAllComponents(project);
LOGGER.debug("Performing component repository metadata analysis against " + components.size() + " components in project: " + project.getUuid());
for (final Component component: components) {
qm.ensureNoActiveTransaction(); // Workaround for https://github.com/DependencyTrack/dependency-track/issues/2677
analyze(qm, component);
}
LOGGER.debug("Completed component repository metadata analysis against " + components.size() + " components in project: " + project.getUuid());
Expand Down