Я разрабатываю небольшое приложение на Java с использованием Spring framework. В рамках этого проекта я разработал инструмент командной строки в этом весеннем проекте, который читается в CSV-файле и вставляет его в базу данных MySQL.Spring - использование управления аннотационными транзакциями в инструменте командной строки
Я хотел бы использовать собственное управление сделками Soring для этой цели, и я нахожу аннотационный метод, используя @Transactional
привлекательный. Проблема в том, что функция с этой аннотацией не откатывается, даже если генерируется исключение.
Это небольшая часть моего кода, я считаю, имеет отношение к этому вопросу:
public static void main(String[] args) throws Exception {
//some variables and stuff here
//getting application context
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
JdbcOperations jdbcOperations = applicationContext.getBean("jdbcOperations", JdbcOperations.class);
UserDaoImpl userDaoImpl = applicationContext.getBean("userDao", UserDaoImpl.class);
DBDaoImpl DBDaoImpl = applicationContext.getBean("dbDao", DBDaoImpl.class);
UserDetailImporterTool importerTool = new UserDetailImporterTool(jdbcOperations, DBDaoImpl, userDaoImpl);
//this functions calls a DAO
importerTool.execute(users, userFollowingMapCSV, batchSize);
}
Это функция Execute(), который вызывается формой указанных выше main()
:
public int execute(List<User> users, String userFollowingMapCSV, int batchSize) throws Exception{
// stuff here
int numSuccessfulInsertions = userDaoImpl.insert(users, jdbcOperations, batchSize);
// stuff here
}
Это функция insert()
, вызываемая от execute()
, функция, указанная выше:
@Override
public int insert(@Nonnull List<User> user,
@Nonnull JdbcOperations jdbcOperations,
int batchSize) throws Exception
{
//stuff here
try {
insertBatch(jdbcOperations,
userArgsList,
userDetailArgsList,
officialDetailArgsList,
residentialDetailArgsList
);
} catch (Exception e) {
LOGGER.warning("ERROR");
}
}
// stuff here
}
И, наконец, это insertBatch()
функция в DAO, на которой управление транзакциями применяется на:
@Transactional("dataSourceTransactionManager")
private void insertBatch(JdbcOperations jdbcOperations,
List<Object[]> userArgsList,
List<Object[]> userDetailArgsList,
List<Object[]> officialDetailArgsList,
List<Object[]> residentialDetailArgsList
) throws Exception
{
try {
jdbcOperations.batchUpdate(userSql, userArgsList);
jdbcOperations.batchUpdate(userDetailSql, userDetailArgsList);
jdbcOperations.batchUpdate(officialDetailSql, officialDetailArgsList);
jdbcOperations.batchUpdate(residentailDetailSql, residentialDetailArgsList);
} catch (Exception e) {
LOGGER.warning(debugMessageIndicator + " Batch failed to insert. Error : " + e.getMessage());
throw new Exception();
}
}
И, наконец, (я обещаю, что это последний фрагмент: P) это мой конфигурационный файл боб:
@EnableTransactionManagement
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@PropertySource("classpath:application.properties")
public class BeanConfig {
private static final String VALIDATION_QUERY = "SELECT 1";
@Autowired
private Environment env;
@Bean
public BasicDataSource dataSource() {
String driverClassName = env.getProperty("db.driverClassName");
String jdbcUrl = env.getProperty("db.jdbcUrl");
String username = env.getProperty("db.username");
String password = env.getProperty("db.password");
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName(driverClassName);
basicDataSource.setUrl(jdbcUrl);
basicDataSource.setUsername(username);
basicDataSource.setPassword(password);
basicDataSource.setValidationQuery(VALIDATION_QUERY);
basicDataSource.setValidationQueryTimeout(1);
basicDataSource.setTestOnBorrow(true);
basicDataSource.setTestWhileIdle(true);
return basicDataSource;
}
@Bean
public JdbcOperations jdbcOperations() {
BasicDataSource dataSource = dataSource();
return new JdbcTemplate(dataSource);
}
@Bean
public UserDAO userDao() {
return new UserDaoImpl();
}
@Bean
public DBDao dbDao() {
return new DBDaoImpl();
}
@Bean
public PlatformTransactionManager transactionManager(){
BasicDataSource dataSource = dataSource();
return new DataSourceTransactionManager(dataSource);
}
}
Я считаю, что все это требовалось, чтобы увидеть полный поток управления. Как вы можете видеть, несмотря на то, что я удаляю исключение, откат не выполняется. Мне сказал кто-то, что я не могу использовать управление аннотационными транзакциями, если я не развожу WAR-файл проекта на Tomcat. Прямо сейчас я запускаю это из командной строки через maven.
Это действительно так, что я не могу использовать @Transactional
без развертывания? Существуют ли какие-либо ошибки, препятствующие выполнению формы отката?
Я попытался установить auto commit на false в DataSource
bean, но без успеха. Любые указатели будут полезны.
с использованием любой аннотации для этого конкретного класса -> UserDetailImporterTool ?? это должно быть в области @Transactional. Если вы не аннотировали этот класс, добавьте @Transactional (rollbackFor = Exception.class) в этот класс. Надеюсь, что работает – ManinGreen