我有一个spring boot项目,我试图在其中从内部和事件侦听器中将一些数据保存在MySql表中。
我正在使用Spring Boot v1.5.10.RELEASE , JDK 1.8 和 MySql 5.7
我已经在我的项目中创建了一个自定义事件( TestEvent
),并为此事件创建了以下异步侦听器。
@Component
public class TestListener implements ApplicationListener<TestEvent> {
private TestService testService;
@Autowired
public JobCreatedListener(TestService testService) {
this.testService = testService;
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void onApplicationEvent(TestEvent applicationEvent) {
testService.save(1L,"One");
}
}
有一个 TestService
服务类,负责保存数据。
@Service
public class TestService {
@Autowired
private TestEntityRepository testEntityRepository;
@Transactional
public TestEntity save(long id, String name) {
TestEntity entity = new TestEntity();
entity.setId(id);
entity.setName(name);
return testEntityRepository.save(entity);
}
}
我面临的问题是,触发此侦听器时,方法 testService.save(1L,"One")
成功执行(没有任何错误或异常),但是数据未保存在表中。
但是,当我从控制器调用相同的方法时,它会成功执行并将数据保存在表中。
我尝试用 @Transactional(propagation = Propagation.REQUIRES_NEW)
注释我的方法,但也没有任何区别。
我不确定这是什么问题。任何帮助表示赞赏。
实体和存储库类如下。
TestEntity
@Entity
@Table(name = "testentity")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class TestEntity implements Serializable {
private long id;
private String name;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
@Column(name = "name", length = 128)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
TestEntityRepository
@Repository
public interface TestEntityRepository extends JpaRepository<TestEntity, Long>, JpaSpecificationExecutor<TestEntity> {
}
答案 0 :(得分:0)
尝试在@Transactional
批注中显式添加transactionManager。可能是问题所在。
@Transactional(propagation = Propagation.REQUIRES_NEW, value= YOUR_TXN_MANAGER)
您的YOUR_TXN_MANAGER
必须与您直接尝试从控制器方法调用同一服务时使用的服务相同。
还要在存储库中添加相同的定义。
@Transactional(value = YOUR_TXN_MANAGER)
@Repository
public interface TestEntityRepository extends JpaRepository<TestEntity, Long>, JpaSpecificationExecutor<TestEntity> {
}
答案 1 :(得分:0)
尝试将 @TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
添加到您的处理程序方法
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void onApplicationEvent(TestEvent applicationEvent) {
testService.save(1L,"One");
}