Java 为什么通过注释设置超时的ChainedTransactionManager不工作?弹簧靴
应用程序:Java 为什么通过注释设置超时的ChainedTransactionManager不工作?弹簧靴,java,spring,postgresql,amazon-rds,transactionmanager,Java,Spring,Postgresql,Amazon Rds,Transactionmanager,应用程序: Spring boot版本2.2.13.0发布 postgresql版本42.2.10 石英版本2.3.2 石英作业版本2.3.2 我已经实现了一个job quartz,它调用@Service bean中实现的方法。在这种方法中,有与两个数据库(Oracle和PostgreSql)的交互。每个数据库都使用Hikari连接池进行序列化 配置bean中的Postgresql数据库: @Bean(value="sreDataSource")
- Spring boot版本2.2.13.0发布
- postgresql版本42.2.10
- 石英版本2.3.2
- 石英作业版本2.3.2
@Bean(value="sreDataSource")
public DataSource dataSource() {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName(driverClassName);
hikariConfig.setJdbcUrl(datasourceUrl);
hikariConfig.setUsername(datasourceUsername);
hikariConfig.setPassword(datasourcePassword);
hikariConfig.setConnectionInitSql("set time zone 'UTC'");
hikariConfig.setMaximumPoolSize(maxPoolSize);
hikariConfig.setConnectionTestQuery("SELECT 1");
hikariConfig.setPoolName("springHikariCP");
return new HikariDataSource(hikariConfig);
}
/**
* @return {@link JdbcTemplate}
*/
@Bean(value="sreJdbcTemplate")
public JdbcTemplate jdbcTemplate() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
jdbcTemplate.setFetchSize(Integer.parseInt(fetchSize));
jdbcTemplate.setQueryTimeout(60);
return jdbcTemplate;
}
/**
* Create the namedJdbcTemplate bean for the SRE database
* @return {@link NamedParameterJdbcTemplate}
*/
@Bean(value="sreNamedParameterJdbcTemplate")
public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
return new NamedParameterJdbcTemplate(jdbcTemplate());
}
/**
* @param dataSource
* @return {@link PlatformTransactionManager}
*/
@Bean(value="sreTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("sreDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* @param sreTransactionManager
* @param assetTransactionManager
* @return {@link ChainedTransactionManager}
*/
@Bean(value="chainedTransactionManager")
public ChainedTransactionManager transactionManager(@Qualifier("sreTransactionManager") PlatformTransactionManager sreTransactionManager,
@Qualifier("assetTransactionManager") PlatformTransactionManager assetTransactionManager) {
return new ChainedTransactionManager(sreTransactionManager, assetTransactionManager);
}
/**
* Datasource
* @return Datasource
*/
@Bean(value="assetDataSource")
public DataSource dataSource() {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName(driverClassName);
hikariConfig.setJdbcUrl(datasourceUrl);
hikariConfig.setUsername(datasourceUsername);
hikariConfig.setPassword(datasourcePassword);
hikariConfig.addDataSourceProperty("oracle.jdbc.timezoneAsRegion", "false");
hikariConfig.setMaximumPoolSize(maxPoolSize);
hikariConfig.setConnectionTestQuery("SELECT 1 from dual");
hikariConfig.setPoolName("springHikariAssetCp");
return new HikariDataSource(hikariConfig);
}
/**
* JDBCTemplate
* @return JDBCTemplate
*/
@Bean(value="assetJdbcTemplate")
public JdbcTemplate jdbcTemplate() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
jdbcTemplate.setFetchSize(Integer.parseInt(fetchSize));
jdbcTemplate.setQueryTimeout(60);
return jdbcTemplate;
}
/**
* Create the namedJdbcTemplate bean for the RMD database
* @return NamedParameterJdbcTemplate
*/
@Bean(value="assetNamedParameterJdbcTemplate")
public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
return new NamedParameterJdbcTemplate(jdbcTemplate());
}
/**
* Create transaction manager
* @param dataSource Datasource
* @return transaction manager
*/
@Bean(value="assetTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("assetDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
配置bean中的Oracle数据库:
@Bean(value="sreDataSource")
public DataSource dataSource() {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName(driverClassName);
hikariConfig.setJdbcUrl(datasourceUrl);
hikariConfig.setUsername(datasourceUsername);
hikariConfig.setPassword(datasourcePassword);
hikariConfig.setConnectionInitSql("set time zone 'UTC'");
hikariConfig.setMaximumPoolSize(maxPoolSize);
hikariConfig.setConnectionTestQuery("SELECT 1");
hikariConfig.setPoolName("springHikariCP");
return new HikariDataSource(hikariConfig);
}
/**
* @return {@link JdbcTemplate}
*/
@Bean(value="sreJdbcTemplate")
public JdbcTemplate jdbcTemplate() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
jdbcTemplate.setFetchSize(Integer.parseInt(fetchSize));
jdbcTemplate.setQueryTimeout(60);
return jdbcTemplate;
}
/**
* Create the namedJdbcTemplate bean for the SRE database
* @return {@link NamedParameterJdbcTemplate}
*/
@Bean(value="sreNamedParameterJdbcTemplate")
public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
return new NamedParameterJdbcTemplate(jdbcTemplate());
}
/**
* @param dataSource
* @return {@link PlatformTransactionManager}
*/
@Bean(value="sreTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("sreDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* @param sreTransactionManager
* @param assetTransactionManager
* @return {@link ChainedTransactionManager}
*/
@Bean(value="chainedTransactionManager")
public ChainedTransactionManager transactionManager(@Qualifier("sreTransactionManager") PlatformTransactionManager sreTransactionManager,
@Qualifier("assetTransactionManager") PlatformTransactionManager assetTransactionManager) {
return new ChainedTransactionManager(sreTransactionManager, assetTransactionManager);
}
/**
* Datasource
* @return Datasource
*/
@Bean(value="assetDataSource")
public DataSource dataSource() {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName(driverClassName);
hikariConfig.setJdbcUrl(datasourceUrl);
hikariConfig.setUsername(datasourceUsername);
hikariConfig.setPassword(datasourcePassword);
hikariConfig.addDataSourceProperty("oracle.jdbc.timezoneAsRegion", "false");
hikariConfig.setMaximumPoolSize(maxPoolSize);
hikariConfig.setConnectionTestQuery("SELECT 1 from dual");
hikariConfig.setPoolName("springHikariAssetCp");
return new HikariDataSource(hikariConfig);
}
/**
* JDBCTemplate
* @return JDBCTemplate
*/
@Bean(value="assetJdbcTemplate")
public JdbcTemplate jdbcTemplate() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
jdbcTemplate.setFetchSize(Integer.parseInt(fetchSize));
jdbcTemplate.setQueryTimeout(60);
return jdbcTemplate;
}
/**
* Create the namedJdbcTemplate bean for the RMD database
* @return NamedParameterJdbcTemplate
*/
@Bean(value="assetNamedParameterJdbcTemplate")
public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
return new NamedParameterJdbcTemplate(jdbcTemplate());
}
/**
* Create transaction manager
* @param dataSource Datasource
* @return transaction manager
*/
@Bean(value="assetTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("assetDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
服务bean是从集群中的job quartz调用的。服务bean的定义如下:
/**
* @author sgalgani
*
*/
@Service("processSreService")
@Transactional("chainedTransactionManager")
public class ProcessSreServiceImpl implements ProcessSreService {
private static final Logger LOGGER = LogManager.getLogger(ProcessSreServiceImpl.class);
@Autowired
@Qualifier("historianService")
private HistorianService historianService;
@Autowired
@Qualifier("sreEvolutionService")
private SreEvolutionService sreEvolutionService;
@Autowired
@Qualifier("assetService")
private AssetService assetService;
@Autowired
@Qualifier("configService")
private ConfigService configService;
@Autowired
@Qualifier("engineSupportService")
private EngineSupportService engineSupportService;
@Autowired
@Qualifier("tagAvailabilityService")
private TagAvailabilityService tagAvailabilityService;
@Autowired
@Qualifier("engineTransformService")
private EngineTransformService engineTransformService;
@Autowired
@Qualifier("quarantineService")
private QuarantineService quarantineService;
@Autowired
@Qualifier("simpleRuleEventService")
private SimpleRuleEventService simpleRuleEventService;
@Value("${save.oracle.temporary.results}")
private boolean saveOracleTemporaryResults;
@Value("${enable.save.local.db.alerts}")
private boolean enableSaveLocalDbAlerts;
@Value("${simple.rule.event.service.enable}")
private boolean simpleRuleEventServiceEnable;
@SuppressWarnings("javadoc")
@Override
@Transactional(value = "chainedTransactionManager", rollbackFor = Exception.class, timeout = 120)
public void processSre(Sre sre, List<TagLastTimestamp> tagsLastTimestamp, Metric metrics) throws Exception {
LOGGER.info("[processSre] for JobId : {} and lineup: {} ",sre.getId(), sre.getLineupId() );
/**
*@作者斯加加尼
*
*/
@服务(“流程服务”)
@事务(“链接事务管理器”)
公共类ProcessReserviceImpl实现ProcessReservice{
私有静态最终记录器Logger=LogManager.getLogger(ProcessSreServiceImpl.class);
@自动连线
@限定词(“历史服务”)
私人历史服务历史服务;
@自动连线
@限定符(“srevolutionservice”)
私有的srevolutionservice srevolutionservice;
@自动连线
@限定符(“资产服务”)
私人资产服务资产服务;
@自动连线
@限定符(“配置服务”)
专用配置服务配置服务;
@自动连线
@限定符(“引擎支持服务”)
私人发动机支持服务发动机支持服务;
@自动连线
@限定符(“tagAvailabilityService”)
专用标记可用性服务标记可用性服务;
@自动连线
@限定符(“engineTransformService”)
专用EngineTransformService EngineTransformService;
@自动连线
@限定词(“检疫服务”)
私人检疫服务检疫服务;
@自动连线
@限定符(“simpleRuleEventService”)
私有SimpleRuleEventService SimpleRuleEventService;
@值(${save.oracle.temporary.results}”)
私有布尔存储库临时结果;
@值(${enable.save.local.db.alerts}”)
私有布尔启用SAVELOCALDBALERTS;
@值(${simple.rule.event.service.enable})
私有布尔simpleRuleEventServiceEnable;
@抑制警告(“javadoc”)
@凌驾
@事务性(value=“chainedTransactionManager”,rollboor=Exception.class,超时=120)
public void processSre(Sre Sre,List tagslattimestamp,Metric metrics)引发异常{
LOGGER.info(“[processSre]用于JobId:{}和lineup:{}”,sre.getId(),sre.getLineupId());
在Amazon RDS postgresql上执行故障切换数据库操作(与数据库的连接丢失)后,我会在120秒后出现事务超时异常,但超时不起作用,原因是什么?我解决了设置属性的问题,如以下文章所述: [https://www.theguardian.com/info/2019/dec/02/faster-postgresql-connection-recovery] 我的代码添加到配置HikariCP中:
hikariConfig.addDataSourceProperty("socketTimeout", "120");
socketTimeout为120秒,因此在任何情况下,属性都会在超时后引发以下异常:
Caused by: java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) ~[?:?]
at java.net.SocketInputStream.socketRead(SocketInputStream.java:115) ~[?:?]
at java.net.SocketInputStream.read(SocketInputStream.java:168) ~[?:?]
at java.net.SocketInputStream.read(SocketInputStream.java:140) ~[?:?]
at sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:448) ~[?:?]
at sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:68) ~[?:?]
at sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1103) ~[?:?]
at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:823) ~[?:?]
at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:161) ~[postgresql-42.2.10.jar!/:42.2.10]
at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:128) ~[postgresql-42.2.10.jar!/:42.2.10]
at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:113) ~[postgresql-42.2.10.jar!/:42.2.10]
at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:73) ~[postgresql-42.2.10.jar!/:42.2.10]
at org.postgresql.core.PGStream.receiveChar(PGStream.java:370) ~[postgresql-42.2.10.jar!/:42.2.10]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2015) ~[postgresql-42.2.10.jar!/:42.2.10]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:311) ~[postgresql-42.2.10.jar!/:42.2.10]... 17 more
请不要将代码作为图像发布,因为这是完全不可读的。只需将代码作为代码发布。好的,我编辑了图像部分。我认为在AWS RDS实例DB PostgreSQL上执行故障转移操作期间,HikariCP连接引起的问题仍然挂起。但是事务超时不起作用。本文介绍了AWS RDS实例和我保留进行测试以解决问题并给出答案的权利。