简体   繁体   中英

Commit on jdbcTemplate or DataSource

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.

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

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

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM