gpt4 book ai didi

java - Spring调度线程未访问数据库

转载 作者:太空宇宙 更新时间:2023-11-04 13:32:08 28 4
gpt4 key购买 nike

我想要实现的目标是每 30 分钟安排一次对数据库的查询,该查询将为我带来许多记录,并需要安排许多新任务,这些新任务将对我的数据库执行新的 CRUD 操作和一些其他操作。

首先,我使用 @EnableScheduling 来安排“SELECT”查询

@Service
@EnableScheduling
public class ScheduleUpdatesTransaction {
final static Logger logger = Logger.getLogger(ScheduleUpdatesTransaction.class);

@Scheduled(fixedDelay = 10000)
public void executeTransaction() {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);

List<Object[]> programUpdatesList = playerDAO.getUpdatesByTimeIterval(myCustomDateTime);//Ok, it access database an retrieve data

for(Object[] element: programUpdatesList){
Long seconds = Long.parseLong(element[0].toString());
Long myKey = Long.parseLong(element[1].toString());
executor.schedule(new ScheduleThreadTransaction(myKey), seconds , TimeUnit.SECONDS);//Ok, it triggers the task
}

executor.shutdown();
}
}

这是 ScheduleThreadTransaction 类:

@Component
public class ScheduleThreadTransaction implements Runnable{

@Autowired
private PlayerTaskDAO playerTaskDAO;

private Long myIdentificator;

public ScheduleThreadTransaction() {
super();
}

public ScheduleThreadTransaction(Long identificator) {
myIdentificator = identificator;
}

public void run() {
try{

PlayerTask playerTask = playerTaskDAO.findOne(myIdentificator);// not working, java.lang.NullPointerException

//More CRUD operations here

}catch(Exception e){
e.printStackTrace();
}
}


public Long getMyIdentificator() {
return myIdentificator;
}

public void setMyIdentificator(Long myIdentificator) {
this.myIdentificator = myIdentificator;
}

}

问题是当调用findOne时,我得到NullPointerException。有什么建议吗?我正在使用 Spring 4 和 JPA 2.1。

编辑:

我在配置中做了一些更改,这是我的 XML 配置:

<context:component-scan base-package="com.myproject"/>

<mvc:annotation-driven>
<mvc:message-converters>
<bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">

<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="serializationInclusion" value="NON_NULL"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>


<mvc:resources mapping="/images/*" location="/images/" />

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="persistenceUnitName" value="myProjectPersistence" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>

<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="HSQL" />
<property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" />
</bean>

<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/myConection" />
<property name="username" value="123456" />
<property name="password" value="654321" />
</bean>

<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="resourceLoaderPath" value="/WEB-INF/velocity/"/>
</bean>

<bean id="statusUpdateService" class="com.myproject.StatusUpdateService" />

<bean id="scheduledExecutorFactoryBean" class="org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean" />

<bean id="scheduleThreadTransactionService" class="com.myproject.ScheduleThreadTransactionService" />

这是 ScheduleUpdatesTransaction 类:

@Service
@EnableScheduling
public class ScheduleUpdatesTransaction {
final static Logger logger = Logger.getLogger(ScheduleUpdatesTransaction.class);

@Autowired
private PlayerCoreUpdateDAO playerCoreUpdateDAO;

@Autowired
StatusUpdateService statusUpdateService;

@Scheduled(fixedDelay = 100000)
public void executeTransaction() {
Util util = new Util();

List<Object[]> programUpdatesList = playerCoreUpdateDAO.getWeaponUpdatesByTimeIterval(new Date());

for(Object[] element: programUpdatesList){
Long seconds = Long.parseLong(element[2].toString());
String finishDate =element[3].toString();
Long myUpdateKey = Long.parseLong(element[0].toString());

System.out.println("UPGRADETIME " + seconds + " FINISHUPGRADETIME " + myUpdateKey);

statusUpdateService.executeTransaction(seconds, myUpdateKey);
}
}
}

StatusUpdateService 类:

@Service
public class StatusUpdateService {
final static Logger logger = Logger.getLogger(StatusUpdateService.class);

@Autowired
private ScheduledExecutorFactoryBean scheduledExecutorFactoryBean;

@Autowired
private Provider<ScheduleThreadTransactionService> runnableFactory;

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void executeTransaction(Long seconds, Long myUpdateKey){
try{
ScheduledExecutorService executor = scheduledExecutorFactoryBean.getObject();

ScheduleThreadTransactionService runnable = runnableFactory.get();

runnable.setElementKey(myUpdateKey);

executor.schedule(runnable, seconds, TimeUnit.SECONDS);

}catch(Exception e){
logger.error(e);
}
}

}

最后是 ScheduleThreadTransactionService 类:

@Service
public class ScheduleThreadTransactionService implements Runnable{
final static Logger logger = Logger.getLogger(ScheduleThreadTransactionService.class);

private Long elementKey;

public ScheduleThreadTransactionService() {

}

public ScheduleThreadTransactionService(Long elementKey) {
this.elementKey = elementKey;
}

@Autowired
private PlayerCoreUpdateDAO playerCoreUpdateDAO;
//Adding @transactional throws an error
public void run() {
try{
PlayerCoreUpdate playerCoreUpdate = playerCoreUpdateDAO.findOne(elementKey);//It works!
playerCoreUpdateDAO.update(playerCoreUpdate);//Didn't work, need @transactional

}catch(Exception e){
logger.error(e);
}
}

public Long getElementKey() {
return elementKey;
}

public void setElementKey(Long elementKey) {
this.elementKey = elementKey;
}

public PlayerCoreUpdateDAO getPlayerCoreUpdateDAO() {
return playerCoreUpdateDAO;
}

public void setPlayerCoreUpdateDAO(PlayerCoreUpdateDAO playerCoreUpdateDAO) {
this.playerCoreUpdateDAO = playerCoreUpdateDAO;
}

}

添加 @Transactional 给我这个错误:

2015-09-28 12:33:32,840 ScheduledExecutorFactoryBean-1 错误 service.StatusUpdateService - org.springframework.beans.factory.NoSuchBeanDefinitionException:没有找到依赖项 [com.myproject.ScheduleThreadTransactionService] 类型的合格 bean:预计至少有 1 个有资格作为此依赖项的 Autowiring 候选者的 bean。依赖注释:{@org.springframework.beans.factory.annotation.Autowired(required=true)}

是否有一个简短的修复程序可以让这个东西运行?

问候。

最佳答案

您正在使用 new 来实例化可运行的 spring 组件。如果您手动实例化,Spring 容器将无法注入(inject)依赖项。

您需要从 bean 工厂获取可运行实例。更简洁的方法是使用工厂和查找方法注入(inject)。

如果您的所有 spring 配置都使用注释,则等效的查找方法将是

在 sheduleThreadTransaction 类中进行以下更改

@Autowired
private javax.inject.Provider<ScheduleThreadTransaction> runnableFactory;

在你的executeTransaction方法中

 ScheduleThreadTransaction runnable = runnableFactory.get();
runnable.setIdentifier(myIdentifier);

关于java - Spring调度线程未访问数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32065695/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com