好像spring忽略了服务类上的@Transactional
注释
如果我们手动创建tx bean可以正常工作
@EnableTransactionManagement
@org.springframework.context.annotation.Configuration
@EnableJpaRepositories(basePackages = { DatabaseConstants.SPRING_DATA_REPO_BASE_PACKAGE }, entityManagerFactoryRef = DatabaseConstants.SPRING_DATA_ENTITY_MANAGER_FACTORY)
public class DatabaseConfig {
private static final Logger LOG = LoggerFactory.getLogger(DatabaseConfig.class);
@Bean
public DataSource dataSource(Configuration dataBaseConfig) throws Exception {
AbstractRoutingDataSource dataSource = new ShardSourceRouter();
Map<Object, Object> targetDataSources = new HashMap<>();
for (int i = 1; i <= CCMConfigUtil.getTotalShards(); i++) {
targetDataSources.put(ShardDatabase.getShardDatabase(i), createDataSource(i, dataBaseConfig));
}
dataSource.setTargetDataSources(targetDataSources);
dataSource.setDefaultTargetDataSource(targetDataSources.get(ShardDatabase.SHARD_ONE));
return dataSource;
}
private DataSource createDataSource(int shardNum, Configuration dataBaseConfig) throws Exception {
JSONObject shardsConfig = new JSONObject(dataBaseConfig.getString(DatabaseConstants.SHARDS_CONFIG));
JSONObject shard = shardsConfig.getJSONObject(String.valueOf(shardNum));
DataSourceFactory dataSourceFactory = (DataSourceFactory) dataSourceFactoryLocatorBean().getObject();
FMSDataSource fmsDataSource = dataSourceFactory.getFMSDataSource(shard
.getString(DatabaseConstants.DATASOURCE_POOL));
return fmsDataSource.createDataSource(shard.getJSONObject(DatabaseConstants.PROPERTIES), dataBaseConfig);
}
@Bean
public LocalContainerEntityManagerFactoryBean fmsEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = null;
try {
Configuration dataBaseConfig = CCMConfigUtil.getDataBaseConfig(System
.getProperty(DatabaseConstants.APPLICATION_NAME));
em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource(dataBaseConfig));
em.setPackagesToScan(new String[] { DatabaseConstants.SPRING_DATA_ENTITIES_BASE_PACKAGE });
em.setPersistenceUnitName(DatabaseConstants.PERSISTENCE_UNIT_NAME);
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaPropertyMap(getJPAProperties(new JSONObject(dataBaseConfig
.getString(DatabaseConstants.JPA_PROPERTIES))));
em.afterPropertiesSet();
LOG.info("Initialized EntityManagerFactory for PersistenceUnitName {}",
DatabaseConstants.PERSISTENCE_UNIT_NAME);
} catch (final Exception e) {
LOG.error("Exception while initialize the EntityManagerFactory {}", e);
throw new RuntimeException("Failed to initialize the EntityManagerFactory", e);
}
return em;
}
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
LocalContainerEntityManagerFactoryBean entityManagerFactory = fmsEntityManagerFactory();
transactionManager.setEntityManagerFactory(entityManagerFactory.getObject());
transactionManager.setDataSource(entityManagerFactory.getDataSource());
return transactionManager;
}
}
@Service
public class FulfillmentRequestManager {
@Autowired
private RequestFulfillmentService requestFulfillmentService;
@Transactional("transactionManager")
public Long createFulfillmentRequest(String buId, String martId, FulfillmentRequest fulfillmentRequest)
throws Exception {
requestFulfillmentService.save(fulfillmentRequestDO, shard);
}
}
@Service
public class RequestFulfillmentService {
@Autowired
private FulfillmentRequestRepository fulfillmentRequestRepository;
public FulfillmentRequestDO save(FulfillmentRequestDO fulfillmentRequestDO, long shard) {
FulfillmentRequestDO fulfillmentRequestDOSaved = null;
Stopwatch stopwatch = Stopwatch.createStarted();
ShardContext.setCurrentShard(ShardDatabase.getShardDatabase(shard));
fulfillmentRequestDOSaved = fulfillmentRequestRepository.save(fulfillmentRequestDO);
LOGGER.info(SplunkLog.getDBLatency(className, "save", DBAction.FetchLatency.name(),
stopwatch.elapsed(TimeUnit.MILLISECONDS)));
ShardContext.clear();
return fulfillmentRequestDOSaved;
}
}
@Repository
public interface FulfillmentRequestRepository extends JpaRepository<FulfillmentRequestDO, Long> {
}
我在使用@Transactional
的类的包中遇到了一些问题。
是否需要添加任何特定的配置来识别只能使用事务注释的类。
或者我定义数据库配置的方式有任何问题。
如果我们手动创建tx bean并在其类中自动连线,则其工作正常
答案 0 :(得分:0)
在方法m2()上使用@Transaction批注,该方法是从同一类的另一个方法m1()调用的。从外部调用m1()的地方。
由于未从外部spring代理中调用m2(),因此被传递。