Skip to content
Open
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
1 change: 1 addition & 0 deletions changes/en-us/2.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Add changes here for all PR submitted to the 2.x branch.
- [[#7644](https://github.com/apache/incubator-seata/pull/7644)] fix the compatibility issue of spotless when java 25
- [[#7662](https://github.com/apache/incubator-seata/pull/7662)] ensure visibility of rm and The methods in MockTest are executed in order
- [[#7683](https://github.com/apache/incubator-seata/pull/7683)] Override XABranchXid equals() and hashCode() to fix memory leak in mysql driver
- [[#7705](https://github.com/apache/incubator-seata/pull/7705)] ensure environment is fully loaded before ConfigurationFactory initialization
- [[#7643](https://github.com/apache/incubator-seata/pull/7643)] fix DM transaction rollback not using database auto-increment primary keys


Expand Down
1 change: 1 addition & 0 deletions changes/zh-cn/2.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
- [[#7644](https://github.com/apache/incubator-seata/pull/7644)] 修复JAVA25时spotless的兼容性问题
- [[#7662](https://github.com/apache/incubator-seata/pull/7662)] 确保 rm 的可见性,并且 MockTest 中的方法按顺序执行
- [[#7683](https://github.com/apache/incubator-seata/pull/7683)] 重写 XABranchXid的equals和hashCode,解决mysql driver内存泄漏问题
- [[#7705](https://github.com/apache/incubator-seata/pull/7705)] 确保环境在 ConfigurationFactory 初始化前完全加载
- [[#7643](https://github.com/apache/incubator-seata/pull/7643)] 修复 DM 事务回滚不使用数据库自动增量主键


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,7 @@ public class SeataPropertiesLoader implements ApplicationContextInitializer<Conf
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
if (ObjectHolder.INSTANCE.getObject(OBJECT_KEY_SPRING_CONFIGURABLE_ENVIRONMENT) == null) {
ObjectHolder.INSTANCE.setObject(
OBJECT_KEY_SPRING_CONFIGURABLE_ENVIRONMENT, applicationContext.getEnvironment());
}
ObjectHolder.INSTANCE.setObject(OBJECT_KEY_SPRING_CONFIGURABLE_ENVIRONMENT, environment);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain why this change was made?
What's the difference between setting the environment only when it's empty and setting it unconditionally (without checking for emptiness)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@funky-eyes Thanks for the review!

The key point: Line 64 triggers ConfigurationFactory static initialization, which needs a complete environment.

With the old null check:

  • EnvironmentPostProcessor sets environment (without application.properties in Spring Cloud)
  • ApplicationContextInitializer skips updating (due to null check)
  • ConfigurationFactory gets incomplete environment → can't read seata.config.type from application.properties

Unconditional update ensures:

  • Always use ApplicationContextInitializer's environment (which has all property sources loaded)
  • Safe because it's always more complete than EnvironmentPostProcessor's

This explains why bootstrap.yml workaround works - it's loaded early enough.

Copy link
Contributor

Choose a reason for hiding this comment

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

So, in Spring Cloud there can be multiple Environment instances, which is why the environment may be incomplete. Otherwise, as I understand it, the same instance shouldn't have this problem, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In Spring Cloud, it's the same Environment instance throughout, but its PropertySources content evolves over time.
Timeline:

  1. SeataClientEnvironmentPostProcessor runs (Order: HIGHEST_PRECEDENCE)

    • Sets environment in ObjectHolder
    • At this point: PropertySources = [bootstrap, system]
    • application.yml NOT loaded yet
  2. ConfigDataEnvironmentPostProcessor runs (Order: HIGHEST_PRECEDENCE + 10)

    • Loads application.yml into the same Environment instance
    • Now: PropertySources = [application, bootstrap, system]

FileConfiguration configuration = ConfigurationFactory.getOriginFileInstanceRegistry();
FileConfig fileConfig = configuration.getFileConfig();
Map<String, Object> configs = fileConfig.getAllConfig();
Expand Down
Loading