spring - Spring boot、jms监听器和数据库事务
问题描述
我在数据库中有 2 条记录,因为在不同的线程中没有找到本地创建和保存的实体。
我的配置是这样的:
@Configuration
@EnableJms
@EnableJpaRepositories
public class MyConfiguration {
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
factory.setRecoveryInterval(5000);
factory.setSessionTransacted(true);
return factory;
}
}
而这个,application.properties:
java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
spring.jms.jndi-name=jms/MyCF
spring.jms.listener.concurrency=5
spring.jms.listener.acknowledge-mode=auto
spring.jms.template.receive-timeout=5000
spring.datasource.jndi-name=jdbc/MyDataSource
spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.generate-ddl=false
我有带有序列生成器的 MyEntity 实体
@Getter
@Setter
@Entity
@Table(name = "MY_ENTITY")
public class MyEntity {
@Id
@Column(name = "ID", nullable = false, precision = 0)
@SequenceGenerator(name="SqName", sequenceName="SQ_ID", allocationSize = 1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SqName")
private long id;
@Basic
@Column(name = "NAME", nullable = true, length = 4000)
private String name;
然后我有我的 JMS 监听器:
@JmsListener(destination="jms/MyQueue")
public void onMessage(Message message) throws Exception {
myService.save(myRepository.findOneByName("name1"));
}
然后我有一个 MyService 类:
@Service
MyServiceImpl implements MyService {
save(MyEntity myEntity) {
if(myEntity == null) myEntity = new MyEntity();
myEntity.setName("name1");
// do something
myRepository.save(myEntity);
}
}
发生了什么,在一行和一个线程中,新创建的实体保存在 myRepository 中(本地,尚未保存在数据库中),并且在另一个线程中的下一行中,当它再次调用保存方法时,它没有找到名称为“的实体” name1”,所以最后我在数据库中有 2 条记录为“name1”。
myRepository.findOneByName("name1") = null;
那么,我应该在 MyServicImpl 类或 JmsListener 中添加 @Transactional 注释以保存方法吗?
我的意思是,我在 MyServiceImpl 类的 save 方法中有 @Transactional,但它从未发生过,但也许只是巧合。
另外,我应该在配置中添加 JtaTransactionManager 吗?
解决方案
这是实体的同名并发更改,考虑乐观锁定
推荐阅读
- python - 如何计算已分箱数据的峰度?
- lodash - 用于检查或值的 lodash js 函数大于或小于零
- android - 如何让 Android 应用程序在没有 root 权限的情况下使用 Iptables
- android - 如何对 RoomDB 中的连接列执行 SELECT 查询?
- regex - 我怎样才能写一个与这个正则表达式相反的正则表达式?
- c# - 缺少与 SQL Server 的连接
- asp.net-core - 将 asp.net mvc .net core 2.2.0 应用程序升级到 .net core 2.2.1 我缺少什么
- python-3.x - Dataframe中的值乘法
- reactjs - 未填充选定的下拉列表值
- react-native - 如何使视频适合 React Native 中的视图?