gpt4 book ai didi

Spring Data JPA 存储库、Spring 中的事务和事件

转载 作者:行者123 更新时间:2023-12-02 00:08:28 24 4
gpt4 key购买 nike

在尝试解决以下问题时,最近几天白发数量急剧增加。我在使用简单的 Spring 3.2 事件机制的自定义事件监听器中使用 Spring Data JPA 存储库。我遇到的问题是,如果 ListenerA 创建一个实体并调用 assetRepository.save(entity)assetRepository.saveAndFlash(entity)从另一个监听器检索同一实体的后续调用失败。原因似乎是 ListenerB 无法在数据库中找到原始实体,它似乎仍在 Hibernate 的缓存中。 ListenerB 锁定实体的触发器是作为线程池中可运行任务执行的结果而触发的事件。这是我的配置:

<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="spring-jpa" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false" />
<property name="database" value="#{appProps.database}" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.hbm2ddl.auto">#{appProps['hibernate.hbm2ddl.auto']}</prop>
<prop key="hibernate.show_sql">#{appProps['hibernate.show_sql']}</prop>
<prop key="hibernate.format_sql">#{appProps['hibernate.format_sql']}</prop>
<prop key="hibernate.search.default.directory_provider">org.hibernate.search.store.impl.FSDirectoryProvider</prop>
<prop key="hibernate.search.default.indexBase">#{appProps.indexLocation}</prop>
<prop key="hibernate.search.lucene_version">#{appProps['hibernate.search.lucene_version']}</prop>
</props>
</property>
</bean>

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

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

我省略了 dataSource 配置,它是定义与 Oracle 数据库的连接的 ComboPooledDataSource 实例。作为旁注,使用组件扫描并且项目是Spring MVC。现在是 Java 类。

监听器A

@Sevice
public class ListenerA implements ApplicationListener<FileUploadedEvent> {

@Autowired
private AssetRepository assetRepository;

@Autowired
private ExecutorService executor; // Triggers runnable task on a Job in Spring's TaskExecutor

@Override
@Transactional
public void onApplicationEvent(FileUploadedEvent event) {

Asset target = event.getTarget();
Job job = new Job(target);
assetRepository.save(job);

executor.execute(job);
}

听众B

@Sevice
public class ListenerB implements ApplicationListener<JobStartedEvent> {

@Autowired
private AssetRepository assetRepository;


@Override
@Transactional
public void onApplicationEvent(JobStartedEvent event) {

String id = event.getJobId();
Job job = assetRepository.findOne(id); // at this point we can not find the job, returns null
job.setStartTime(new DateTime());
job.setStatus(Status.PROCESSING);

assetRepository.save(job);
}

JobStartedEventTaskExecutor 中的可运行任务触发。我在这里做错了什么?我曾尝试使用可识别事务的自定义事件发布者,但这似乎无法解决问题。我还尝试连接适当的服务而不是数据存储库,并从监听器中删除 @Transactional 注释,这也失败了。欢迎任何关于如何解决问题的合理建议。

最佳答案

感谢 @Kresimir Nesek 的提示,我已经设法解决了问题。 .因此解决方案是用适当的服务替换 Spring Data 存储库。这是修改后的类。

听众 A

@Sevice
public class ListenerA implements ApplicationListener<FileUploadedEvent> {

@Autowired
private JobService service;

@Autowired
private ExecutorService executor; // Triggers runnable task on a Job in Spring's TaskExecutor

@Override
public void onApplicationEvent(FileUploadedEvent event) {

Job job = service.initJobForExecution(event.getTarget());

executor.execute(job);
}
}

JobService 方法 initJobForExecution(Asset target) 中,必须用 @Transactional(propagation=Propagation.REQUIRES_NEW) 注释所有内容工作。

听众 B

@Sevice
public class ListenerB implements ApplicationListener<JobStartedEvent> {

@Autowired
private JobService service;


@Override
public void onApplicationEvent(JobStartedEvent event) {
service.updateStatus(event.getJobId(), Status.PROCESSING);
}
}

关于Spring Data JPA 存储库、Spring 中的事务和事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16915147/

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