JdbcTemplateを使用してコミットとロールバックを実行したいと思いました。
私の質問は this thread に基づいています
どのようにコミットまたはロールバックしますか?
jdbcTemplate.commit();
jdbcTemplate.rollback();
または、jdbcTemplateを使用してコミットおよびロールバック機能を実現する他の方法がいくつかあります。
commit
またはrollback
atを呼び出すと、トランザクション境界が宣言的にではなくプログラム的に設定されます。
そのため、 PlatformTransactionManager を取得する必要があります-DAOに挿入し、commit
/rollback
操作を自分で実行します。
サンプルコード:
@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);
}
別のアプローチは TransactionTemplate を取得することです
サンプルコード:
@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);
}
});
}}
使用する @Transactional
。しかしもちろん、その前に、DataSourceTransactionManager
のBean定義を作成する必要があります。
// 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;
}
そして、あなたは@Transactional
。サービスの例:
@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);
}
springトランザクションマネージャー/ jdbcTemplateを正しく構成した場合、トランザクションをロールバックするかどうかを定義するために、常にSpringによって提供される@Transactionalアノテーションを使用できます。ただし、ロールバックを定義していて、jdbcドライバーまたはデータベースがトランザクションを許可していない場合でも(JdbcConnectionでTRANSACTION_ISOLATIONを確認)、Springはトランザクションを使用していることをログに記録しますが、データベースはそれらのポイントを単に無視します。
springでトランザクションを管理する最も簡単な方法は@Transactionalアノテーションであるため、コードは非常にシンプルに見えます。
@Transactional(rollbackFor = Exception.class)
public void doSomething(...) {
...
}
詳細: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html