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.