Je voulais faire commettre et annuler en utilisant jdbcTemplate.
Ma question est basée sur ce fil
Comment puis-je valider ou annuler, dois-je le faire sur jdbcTemplate
jdbcTemplate.commit();
jdbcTemplate.rollback();
Vous pouvez également utiliser les fonctionnalités de validation et d'annulation à l'aide de jdbcTemplate.
Pour appeler commit
ou rollback
à volonté, définissez les limites transactionnelles par programme et non de manière déclarative.
Pour cette raison, vous devez vous procurer le PlatformTransactionManager - l'injecter dans votre DAO et effectuer vous-même l'opération commit
/rollback
.
Exemple de code:
@Autowired private JdbcTemplate jdbcTemplate;
@Autowired private PlatformTransactionManager platformTransactionManager;
//..
public void daoMethod(params) {
DefaultTransactionDefinition paramTransactionDefinition = new DefaultTransactionDefinition();
TransactionStatus status=platformTransactionManager.getTransaction(paramTransactionDefinition );
try{
String sqlQuery = "query";
jdbcTemplate.update(sqlQuery, params);
platformTransactionManager.commit(status);
}catch (Exception e) {
platformTransactionManager.rollback(status);
}
Une autre approche consiste à mettre la main sur TransactionTemplate
Exemple de code:
@Autowired private JdbcTemplate jdbcTemplate;
@Autowired private TransactionTemplate transactionTemplate;
//..
//for operations where query does not return like delete
public void daoMethod(params) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus paramTransactionStatus) {
try{
String sqlQuery = "query";
jdbcTemplate.update(query, params);
}catch (Exception e) {
paramTransactionStatus.setRollbackOnly();
}
}
});
}
//for operations where query does return like insert
public int daoMethod(params) {
return transactionTemplate.execute(new TransactionCallback<Integer>() {
public Integer doInTransaction(TransactionStatus paramTransactionStatus) {
String sqlQuery = "query";
Object[] params = params;
int[] types = myTypes;
return jdbcTemplate.update(sqlQuery,params,types);
}
});
}}
Utilisez @Transactional
. Mais bien sûr, avant cela, vous devrez créer une définition de bean pour DataSourceTransactionManager
:
// Your DataSource bean definition
@Bean
public DataSource dataSource() {
....
}
// Transaction manager bean definition
@Bean
public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}
Et ensuite, vous pouvez utiliser @Transactional
. Exemple de service:
@Service
public class MyServiceImpl {
@Autowired
private MyDAO myDAO;
@Transactional
public void insert(Entity entity) {
myDAO.insert(entity);
}
}
@Configuration
public class ConfigurationApp {
@Bean
public DataSource dataSourceJdbc() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("Oracle.jdbc.driver.OracleDriver");
dataSource.setUrl("jdbc:Oracle:thin:@localhost:1521:orcl");
dataSource.setUsername("hossein");
dataSource.setPassword("myjava123");
dataSource.setDefaultAutoCommit(false);
return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplate() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSourceJdbc());
return jdbcTemplate;
}
@Bean
public DAOImpl dao() {
DAOImpl personDAO = new DAOImpl();
personDAO.setJdbcTemplate(jdbcTemplate());
return personDAO;
}
@Bean
public PersonService personService() {
PersonService personService = new PersonService();
personService.setPersonDAO(dao());
return personService;
}
}
//////////////////////////////////////////
public class Person {
private Integer id;
private String name;
private String family;
private Integer password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFamily() {
return family;
}
public void setFamily(String family) {
this.family = family;
}
public Integer getPassword() {
return password;
}
public void setPassword(Integer password) {
this.password = password;
}
}
/////////////////////////////////////////
import org.Apache.commons.dbcp2.BasicDataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import Java.util.List;
@Repository
public class DAOImpl {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public int add(Person person) {
String sql = "insert into person(id,name,family,password) values(?,?,?,?)";
return this.jdbcTemplate.update(sql, person.getId(), person.getName(), person.getFamily(), person.getPassword());
}
public void commit(){
BasicDataSource basicDataSource= (BasicDataSource) jdbcTemplate.getDataSource();
basicDataSource.setDefaultAutoCommit(true);
}
}
///////////////////////////////////
import org.springframework.stereotype.Service;
import Java.util.List;
@Service
public class PersonService {
private DAOImpl personDAO;
public void setPersonDAO(DAOImpl personDAO){
this.personDAO=personDAO;
}
public void addPerson(Person person) {
personDAO.add(person);
this.personDAO.commit();
}
}
///////////////////////
public class MainApp {
public static void main(String[] args) {
Locale.setDefault(Locale.ENGLISH);
AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(ConfigurationApp.class);
PersonService person=ac.getBean(PersonService.class);
Person person1=new Person();
person1.setId(896);
person1.setName("vali");
person1.setFamily("hassanpoor");
person1.setPassword(12579);
person.addPerson(person1);
}
si vous avez configuré correctement le gestionnaire de transactions spring/jdbcTemplate, vous pouvez toujours utiliser les annotations @Transactional fournies par spring afin de définir le moment où vous souhaitez annuler ou non une transaction. Mais même si vous avez défini une annulation et que votre pilote jdbc ou votre base de données n'autorise pas les transactions (vérifiez TRANSACTION_ISOLATION sur JdbcConnection), alors Spring enregistrera que des transactions sont utilisées, mais la base de données ignore simplement ces points.
le moyen le plus simple de gérer les transactions au printemps est @Transactional, votre code sera donc très simple:
@Transactional(rollbackFor = Exception.class)
public void doSomething(...) {
...
}
en savoir plus: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html