Spring Road (39) - programmatic transaction management based on transaction template

Keywords: JDBC Database MySQL Java

background

The programmatic transaction management based on PlatformTransactionManater implemented in the previous article belongs to a very low-level encapsulation. In fact, the original JDBC transaction operation is encapsulated as an interface and then implemented by a specific implementation class.

In this paper, the TransactionTemplate class is used to encapsulate the fixed process code. Only a few database operations which are regarded as atomic operations need to be put into one method for processing can realize the transaction.

code implementation

Modify the configuration class. Based on the previous registration of platformtransactionmanager type beans, register TransactionTemplate type beans. The code is as follows:

package org.maoge.templatetran;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import com.alibaba.druid.pool.DruidDataSource;
/**
* Spring Configuration class
*/
@Configuration
public class SpringConfig {
   /**
    * Define data source bean s
    */
   @Bean
   public DataSource dataSource() {
   	DruidDataSource dataSource = new DruidDataSource();
   	dataSource.setDriverClassName("com.mysql.jdbc.Driver");
   	dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/myblog?useUnicode=true&characterEncoding=utf-8");
   	dataSource.setUsername("root");
   	dataSource.setPassword("Easy@0122");
   	return dataSource;
   }
   /**
    * Defining transaction management bean s
    */
   @Bean
   public PlatformTransactionManager transactionManager() {
   	DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
   	transactionManager.setDataSource(dataSource());// Inject dataSource
   	return transactionManager;
   }
   /**
    * Define bean s of type TransactionTemplate
    */
   @Bean
   public TransactionTemplate transactionTemplate() {
   	TransactionTemplate transactionTemplate=new TransactionTemplate();
   	transactionTemplate.setTransactionManager(transactionManager());//Inject transaction manager
   	return transactionTemplate;
   }
   /**
    * Configure the namedParameterJdbcTemplate component
    */
   @Bean
   public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
   	NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(dataSource());// Inject dataSource
   	return template;
   }
   /**
    * Register bean s for BlogDao
    */
   @Bean
   public BlogDao blogDao() {
   	BlogDao blogDao = new BlogDao();
   	blogDao.setNamedTemplate(namedParameterJdbcTemplate());// Inject namedParameterJdbcTemplate
   	return blogDao;
   }
}

Data object BlogDo and data operation object BlogDao have no changes:

package org.maoge.templatetran;
import java.util.HashMap;
import java.util.Map;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
/**
* @theme DAO--Blog
* @author maoge
* @date 2020-01-29
*/
public class BlogDao {
   public NamedParameterJdbcTemplate getNamedTemplate() {
   	return namedTemplate;
   }
   public void setNamedTemplate(NamedParameterJdbcTemplate namedTemplate) {
   	this.namedTemplate = namedTemplate;
   }
   private NamedParameterJdbcTemplate namedTemplate;
   /**
    * Newly added
    */
   public void insert(BlogDo blog) {
   	Map<String, Object> map = new HashMap<>();
   	map.put("author", blog.getAuthor());
   	map.put("content", blog.getContent());
   	map.put("title", blog.getTitle());
   	// Attention to use: xxx space
   	namedTemplate.update("insert into blog(author,content,title)values(:author,:content,:title)", map);
   }
}
package org.maoge.templatetran;
/**
 * @theme Data object blog
 * @author maoge
 * @date 2020-01-27
 */
public class BlogDo {
	private Long id;
	private String title;
	private String author;
	private String content;
	// Omit get
}

Test and verify. When using transactions, use the method of TransactionTemplate class:

package org.maoge.templatetran;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

public class Main {
	public static void main(String[] args) {
		// Get container
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
		// Get TransactionTemplate in container
		TransactionTemplate transactionTemplate = (TransactionTemplate) context.getBean("transactionTemplate");
		// Get database operation component in container
		BlogDao blogDao = (BlogDao) context.getBean("blogDao");
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			// Be careful! Operations in this method implement transactions
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus arg0) {
				BlogDo blog = new BlogDo();
				blog.setContent("test");
				blogDao.insert(blog);
				int a = 1 / 0;// An exception occurred, causing the transaction to roll back, so no row of data will be inserted
				blogDao.insert(blog);
			}
		});
	}
}

It should be noted that when the TransactionTemplate is executed, whether there is an exception under check or a runtime exception, the rollback operation will be executed. This is quite in line with our expectations. In the next declarative transaction management, you will find that the default situation is not like this, which is a bit of a pit.

357 original articles published, 240 praised, 530000 visitors+
His message board follow

Posted by laide234 on Sun, 02 Feb 2020 06:34:52 -0800