簡體   English   中英

Spring 啟動、jms 監聽和數據庫事務

[英]Spring boot, jms listener and database transaction

我在數據庫中有 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 class:

@Service
MyServiceImpl implements MyService {
    save(MyEntity myEntity) {
        if(myEntity == null) myEntity = new MyEntity();
        myEntity.setName("name1");
        // do something
        myRepository.save(myEntity);
    }
}

發生了什么,在一行和一個線程中,新創建的實體保存在 myRepository 中(本地,尚未保存在 DB 中),而在另一個線程中的下一行,當它再次調用 save 方法時,它沒有找到名稱為“的實體” name1”,所以最后我在數據庫中有 2 條記錄為“name1”。

myRepository.findOneByName("name1") = null;

那么,我應該在 MyServicImpl class 或 JmsListener 中添加 @Transactional 注釋以保存方法嗎?

我的意思是,我在 MyServiceImpl class 的保存方法中有@Transactional,但它從未發生過,但也許只是巧合。

另外,我應該在配置中添加 JtaTransactionManager 嗎?

這是實體的同名並發更改,考慮樂觀鎖定

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM