Skip to content

Conversation

@jsbxyyx
Copy link
Member

@jsbxyyx jsbxyyx commented Dec 16, 2025

Ⅰ. Describe what this PR did

Ⅱ. Does this pull request fix one issue?

fixes: #7770

Ⅲ. Why don't you add test cases (unit test/integration test)?

Ⅳ. Describe how to verify it

Ⅴ. Special notes for reviews

@jsbxyyx jsbxyyx changed the title optimize: global transaction filter private method optimize: global transaction support non-private methods Dec 16, 2025
@codecov
Copy link

codecov bot commented Dec 16, 2025

Codecov Report

❌ Patch coverage is 75.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.10%. Comparing base (c13207c) to head (258303b).

Files with missing lines Patch % Lines
...r/parser/GlobalTransactionalInterceptorParser.java 75.00% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##                2.x    #7867      +/-   ##
============================================
+ Coverage     71.07%   71.10%   +0.02%     
  Complexity      797      797              
============================================
  Files          1294     1294              
  Lines         49528    49540      +12     
  Branches       5873     5877       +4     
============================================
+ Hits          35202    35225      +23     
+ Misses        11418    11411       -7     
+ Partials       2908     2904       -4     
Files with missing lines Coverage Δ
...r/parser/GlobalTransactionalInterceptorParser.java 67.34% <75.00%> (+2.48%) ⬆️

... and 9 files with indirect coverage changes

Impacted file tree graph

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes global transaction support to include non-private methods by changing the reflection API used to discover annotated methods. The change allows protected and package-private methods with @GlobalTransactional or @GlobalLock annotations to be proxied, while explicitly excluding private methods which cannot be proxied anyway.

Key changes:

  • Switched from getMethods() to getDeclaredMethods() to access non-public methods
  • Added explicit filtering to exclude private methods from proxy consideration
  • Updated both English and Chinese changelogs

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java Changed reflection API from getMethods() to getDeclaredMethods() and added private method filtering
changes/zh-cn/2.x.md Added Chinese changelog entry for PR #7867
changes/en-us/2.x.md Added English changelog entry for PR #7867

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java:122

  • The current implementation processes public methods twice - once through getMethods() (lines 92-105) and again through getDeclaredMethods() (lines 106-122). While the HashSet prevents duplicate entries, this creates unnecessary overhead by checking annotations on the same public methods twice. Consider optimizing by either using only getDeclaredMethods() with modifier checks, or tracking which methods have already been processed to avoid redundant annotation lookups.
                Method[] methods = clazz.getMethods();
                for (Method method : methods) {
                    trxAnno = method.getAnnotation(GlobalTransactional.class);
                    if (trxAnno != null) {
                        methodsToProxy.add(method.getName());
                        result = true;
                    }

                    GlobalLock lockAnno = method.getAnnotation(GlobalLock.class);
                    if (lockAnno != null) {
                        methodsToProxy.add(method.getName());
                        result = true;
                    }
                }
                Method[] declaredMethods = clazz.getDeclaredMethods();
                for (Method method : declaredMethods) {
                    if (Modifier.isPrivate(method.getModifiers())) {
                        continue;
                    }
                    trxAnno = method.getAnnotation(GlobalTransactional.class);
                    if (trxAnno != null) {
                        methodsToProxy.add(method.getName());
                        result = true;
                    }

                    GlobalLock lockAnno = method.getAnnotation(GlobalLock.class);
                    if (lockAnno != null) {
                        methodsToProxy.add(method.getName());
                        result = true;
                    }
                }

integration-tx-api/src/main/java/org/apache/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java:122

  • The annotation processing logic for GlobalLock and GlobalTransactional is duplicated in two separate loops (lines 92-105 and lines 106-122). This duplication makes the code harder to maintain and increases the risk of inconsistencies if changes are needed in the future. Consider extracting the common annotation checking logic into a helper method to reduce duplication.
                    GlobalLock lockAnno = method.getAnnotation(GlobalLock.class);
                    if (lockAnno != null) {
                        methodsToProxy.add(method.getName());
                        result = true;
                    }
                }
                Method[] declaredMethods = clazz.getDeclaredMethods();
                for (Method method : declaredMethods) {
                    if (Modifier.isPrivate(method.getModifiers())) {
                        continue;
                    }
                    trxAnno = method.getAnnotation(GlobalTransactional.class);
                    if (trxAnno != null) {
                        methodsToProxy.add(method.getName());
                        result = true;
                    }

                    GlobalLock lockAnno = method.getAnnotation(GlobalLock.class);
                    if (lockAnno != null) {
                        methodsToProxy.add(method.getName());
                        result = true;
                    }
                }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

private static final Logger LOGGER = LoggerFactory.getLogger(NonPrivateMethodTestClass.class);

@GlobalTransactional(timeoutMills = 300000)
String dftMethod() {
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method name dftMethod uses an unclear abbreviation. Consider renaming to defaultMethod or packagePrivateMethod to better communicate that this method has package-private (default) access visibility. This would make the test class more self-documenting and easier to understand.

Suggested change
String dftMethod() {
String defaultMethod() {

Copilot uses AI. Check for mistakes.
}

@Test
void shouldExcludePrivateMethodsFromProxy() throws Exception {
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test name shouldExcludePrivateMethodsFromProxy doesn't fully capture what the test verifies. The test actually verifies that non-private methods (default and protected) ARE included while private methods are excluded. Consider a more descriptive name like shouldIncludeNonPrivateMethodsAndExcludePrivateMethodsFromProxy or shouldProxyOnlyNonPrivateMethods to better communicate the complete behavior being tested.

Suggested change
void shouldExcludePrivateMethodsFromProxy() throws Exception {
void shouldProxyOnlyNonPrivateMethods() throws Exception {

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

spring mvc supports default modifiers, @GlobalTransactional only support public modifiers.

3 participants