關注這個問題,是因爲我們的項目在使用jpa 和sharding分庫分表以後,在跑test類的時候,save保存不進去數據,但是不報任何錯。然後我把save改成saveAndFlush的時候,開始報這個錯了。注意在service層已經加過@Transactional 註解了。 如果搜這個問題的,多數是因爲沒加@Transactional註解。
沒加sharding分庫分表,是沒問題的,能插進去數據。事務都用的好好的。但是加了sharing以後插入不進去數據了,然後只能通過啓動項目調用 controller 纔行。但是在定時任務裏邊去跑,也插入不進去數據。把save改成 saveAndFlush 就報一個錯誤,報的是沒有事務的錯誤。
於是就很費解了,我明明加了@transactional 註解了,爲啥到了執行這一行,他就報沒有事務呢?
所以就查到 事務管理器上來了。
# # 先說下,如何在springboot中查看事務管理器
@Bean
public Object testBean(PlatformTransactionManager platformTransactionManager){
System.out.println(">>>>>>>>>>>"+platformTransactionManager.getClass().getName());
return new Object();
}
啓動項目,然後在控制檯上就可以看到:
# # 查這個是爲了查看爲什麼我明明添加了@Transactional 註解,但是還是報錯
報這個錯:
org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
可能你看到個錯誤,會覺得是 沒有添加@Transaction註解,但是我明明已經在service層添加過了。
# # 最後解決方案就是
更換一下事務管理器,通過添加一個配置類,就可以替換了。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
import javax.annotation.Resource;
import javax.persistence.EntityManagerFactory;
/**
* @author angus
* @create 2020-03-28 20:21
*/
@Configuration
public class TransactionManagerConfig implements TransactionManagementConfigurer {
@Resource(name="transactionManager")
private PlatformTransactionManager txManager;
// // 創建事務管理器1
// @Bean(name = "txManager1")
// public PlatformTransactionManager txManager(DataSource dataSource) {
// return new DataSourceTransactionManager(dataSource);
// }
// 創建事務管理器
@Bean(name = "transactionManager")
public PlatformTransactionManager txManager(EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
//其返回值代表在擁有多個事務管理器的情況下默認使用的事務管理
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return txManager;
}
}
# # 然後 問題解決了