项目场景
Spring Boot 2.x,集成 atomikos
问题描述
今天在同一个环境启动两个项目时报错,因为两个项目同时涉及到分布式事物和切换数据源相关。
项目集成atomikos后,
org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.transaction.UserTransaction]: Factory method 'userTransaction' threw exception; nested exception is com.atomikos.icatch.SysException: Error in init: Log already in use? tmlog in ./
org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)\n\t... 25 common frames omitted\nCaused by: com.atomikos.icatch.SysException: Error in init: Log already in use? tmlog in ./
com.atomikos.icatch.provider.imp.AssemblerImp.createRepository(AssemblerImp.java:181)
com.atomikos.icatch.provider.imp.AssemblerImp.assembleTransactionService(AssemblerImp.java:156)
com.atomikos.icatch.config.Configuration.assembleSystemComponents(Configuration.java:485)
com.atomikos.icatch.config.Configuration.init(Configuration.java:448)
com.atomikos.icatch.config.UserTransactionServiceImp.initialize(UserTransactionServiceImp.java:105)
com.atomikos.icatch.config.UserTransactionServiceImp.init(UserTransactionServiceImp.java:219)
com.atomikos.icatch.jta.UserTransactionImp.checkSetup(UserTransactionImp.java:59)
com.atomikos.icatch.jta.UserTransactionImp.setTransactionTimeout(UserTransactionImp.java:127)
...
原因分析
在项目中使用atomikos时,如果在同一个环境中部署两个以上这种项目,则可能会报出com.atomikos.icatch.SysException: Error in init(): Log already in use异常,
这个信息是因为atomikos在默认情况下是将console_file_name和log_base_name设置为默认值:tm.out和tmlog0.log,并且会将这两个文件上锁,导致其他线程无法访问,所以当多个项目都未指定这一名称时就会出现上述异常信息。
详细分析
例如,在com.atomikos下的 transactions-4.0.6.jar 包里,有一个类:com.atomikos.icatch.provider.imp.AssemblerImp.java
部分代码如下:
public ConfigProperties initializeProperties() {
Properties defaults = new Properties();
this.loadPropertiesFromClasspath(defaults, "transactions-defaults.properties");
Properties transactionsProperties = new Properties(defaults);
this.loadPropertiesFromClasspath(transactionsProperties, "transactions.properties");
Properties jtaProperties = new Properties(transactionsProperties);
this.loadPropertiesFromClasspath(jtaProperties, "jta.properties");
Properties customProperties = new Properties(jtaProperties);
this.loadPropertiesFromCustomFilePath(customProperties);
Properties finalProperties = new Properties(customProperties);
ConfigProperties configProperties = new ConfigProperties(finalProperties);
this.checkRegistration(configProperties);
return configProperties;
}
从内部实现,可以看出是,首先会加载transactions-defaults.properties文件,后面会去加载自定义配置文件(customProperties),即jta.properties文件。所以思路就是重新指定不同的文件名;
解决方案
在每一个项目中都指定atomikos的文件名称:
在受影响的项目里,新建一个jta.properties文件,添加配置如下:里面属性的值,保证每个项目的名称都不一样
com.atomikos.icatch.log_base_name=service1-tmlog
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/155590.html