Commit on jdbcTemplate or DataSource
Asked Answered
M

5

24

I wanted to do commit and rollback using jdbcTemplate.

My question is based on this thread

How do I commit or rollback, should I do it on jdbcTemplate like

jdbcTemplate.commit();
jdbcTemplate.rollback();

Or there are some other ways to achieve commit and rollback functionality using jdbcTemplate.

Magnetic answered 13/8, 2015 at 8:40 Comment(1)
Use Spring's @Transactional transaction management.Helaina
V
18

To call commit or rollback at will set the transactional boundaries programmatically and not declaratively.

For that reason you have to get hold of the PlatformTransactionManager - inject it that is in your DAO and perform the commit/ rollback operation yourself.

Sample 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);
}

Another approach is to get hold of the TransactionTemplate

Sample 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);
   }
 });
}}
Variegation answered 13/8, 2015 at 9:5 Comment(2)
Thanks. Do I need to set <property name="defaultAutoCommit" value="false" /> at data source level?Magnetic
Why don't you like calling commits programmatically?Ragen
H
14

Use @Transactional. But of course, before of that, you will have to create bean definition for 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;
}

And then you can use @Transactional. Example of service:

@Service
public class MyServiceImpl {

    @Autowired
    private MyDAO myDAO;

    @Transactional
    public void insert(Entity entity) {
       myDAO.insert(entity);
    }
}
Helaina answered 13/8, 2015 at 9:25 Comment(1)
no need to configure dataSourceTransactionManager in SpringBoot 2Miasma
L
1

the easiest way of managing transactions in spring is @Transactional annotation, so your code will look very simple:

@Transactional(rollbackFor = Exception.class)
public void doSomething(...) {
    ...
}

read more: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html

Lunular answered 13/8, 2015 at 8:58 Comment(2)
Thanks. Do I need to set <property name="defaultAutoCommit" value="false" /> at data source level?Magnetic
no, you need just configure txManager-bean in you spring contextLunular
P
1

if you have configured the spring transaction manager / jdbcTemplate correctly , then you could always use the @Transactional annotations provided by spring in order to define when you want a transaction to be rolled back or not. But even if you have defined a rollback and your jdbc driver or your database do not allow transactions (check TRANSACTION_ISOLATION over JdbcConnection), then spring will log that is using transactions but the database will simply ignore those points.

Premiere answered 13/8, 2015 at 9:20 Comment(0)
S
-3
@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);
}
Spasmodic answered 31/10, 2018 at 8:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.