The blog posts on the aforementioned transactions mainly make use of the declarative posture of the @Transactional annotation, which has the advantages of simple use, low intrusiveness and high identifiability (you know you are using the transaction at a glance); however, the drawbacks are obvious, not flexible enough, and not paying attention to it, probably because of the incorrect posture, the transaction will not take effect
This article introduces another transaction usage posture, programmatic transaction with TransactionTemplate
<!-- more -->
I. Configuration
This article focuses on an example demo of jdbcTemplate+transactionTemplate to complete a programmatic transaction
Create a SpringBoot project, version 2.2.1.RELEASE, use mysql as the target database, store engine select Innodb, transaction isolation level RR
1. Project Configuration
In the project pom.xml file, plus spring-boot-starter-jdbc, a DataSourceTransactionManager bean is injected, providing transaction support
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
2. Database Configuration
Go to the spring configuration file application.properties to set up db-related information
## DataSource spring.datasource.url=jdbc:mysql://127.0.0.1:3306/story?useUnicode=true&characterEncoding=UTF-8&useSSL=false spring.datasource.username=root spring.datasource.password=
3. Database
Create a new simple table structure for testing
CREATE TABLE `money` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL DEFAULT '' COMMENT 'User name', `money` int(26) NOT NULL DEFAULT '0' COMMENT 'money', `is_deleted` tinyint(1) NOT NULL DEFAULT '0', `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Creation Time', `update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Update Time', PRIMARY KEY (`id`), KEY `name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=551 DEFAULT CHARSET=utf8mb4;
II. Instructions for use
1. Initialization
Create several pieces of data for transactional operations
@Service public class ManualDemo { @Autowired private TransactionTemplate transactionTemplate; @Autowired private JdbcTemplate jdbcTemplate; @PostConstruct public void init() { String sql = "replace into money (id, name, money) values (220, 'Initialization', 200)"; jdbcTemplate.execute(sql); } }
2. Use case
To demonstrate the nature of transactions, we design a few simple sql operations and throw exceptions that cause a rollback, as follows
- In the doUpdate method, display the update name, output the result of the update, update the money value, and throw an exception expecting the transaction to roll back
private boolean doUpdate(int id) throws Exception { if (this.updateName(id)) { this.query("after updateMoney name", id); if (this.updateMoney(id)) { return true; } } throw new Exception("Parameter Exception"); } private boolean updateName(int id) { String sql = "update money set `name`='To update' where id=" + id; jdbcTemplate.execute(sql); return true; } public void query(String tag, int id) { String sql = "select * from money where id=" + id; Map map = jdbcTemplate.queryForMap(sql); System.out.println(tag + " >>>> " + map); } private boolean updateMoney(int id) { String sql = "update money set `money`= `money` + 10 where id=" + id; jdbcTemplate.execute(sql); return false; }
This logic is familiar if you look at the previous blog posts, except that the doUpdate method does not have the @Transactional annotation added to it, and its calls will not be executed in the transaction at this time
Next, let's look at the core writing of programmatic transactions
public void testTransaction(int id) { transactionTemplate.execute(new TransactionCallback<Boolean>() { @Override public Boolean doInTransaction(TransactionStatus transactionStatus) { try { return doUpdate(id); } catch (Exception e) { transactionStatus.setRollbackOnly(); return false; } } }); }
As above, encapsulate method calls in transactionTemplate.execute calls, marking rollback by setting transactionStatus.setRollbackOnly()
From the previous blog posts, we know that in real use, the isolation level of transactions and the transfer of attributes are also important. In programmatic transactions, of course, they can be set
// Set isolation level transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT); // Setting propagation properties transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
Finally, write a test code to verify that it works
@Component public class TransactionalSample { @Autowired private ManualDemo manualDemo; public void testManualCase() { System.out.println("======= Programmatic Transactions start ========== "); manualDemo.query("transaction before", 220); manualDemo.testTransaction(220); manualDemo.query("transaction end", 220); System.out.println("======= Programmatic Transactions end ========== "); } }
The output is as follows, and the final data big has not been modified
======= Programmatic Transactions start ========== transaction before >>>> {id=220, name=Initialization, money=200, is_deleted=false, create_at=2020-02-03 13:52:39.0, update_at=2020-02-03 13:52:39.0} after updateMoney name >>>> {id=220, name=To update, money=200, is_deleted=false, create_at=2020-02-03 13:52:39.0, update_at=2020-02-03 13:52:39.0} transaction end >>>> {id=220, name=Initialization, money=200, is_deleted=false, create_at=2020-02-03 13:52:39.0, update_at=2020-02-03 13:52:39.0} ======= Programmatic Transactions end ==========
III. Other
0.Series Blog & Source
Series Blog
- Basic Use of DB in 180926-SpringBoot Advanced Text
- 190407-SpringBoot Advanced JdbcTemplate Data Insertion Use Posture Details
- 190412-SpringBoot Advanced JdbcTemplate Data Query Previous
- 190417-SpringBoot Advanced JdbcTemplate Data Query Next
- Data Update and Delete of 190418-SpringBoot Advanced JdbcTemplate
- Declarative Transactional Transactional for the SpringBoot series of tutorials
- Summary of Transaction Isolation Level Knowledge Points for the 200120-SpringBoot Series Tutorials
- Transaction Delivery Properties for the 200202-SpringBoot series of tutorials
- Several case s where transactions for the 200203-SpringBoot series of tutorials do not take effect
Source code
- Project: https://github.com/liuyueyi/spring-boot-demo
- Instance source: https://github.com/liuyueyi/spring-boot-demo/blob/master/spring-boot/101-jdbctemplate-transaction
1.A grey Blog
Unlike letters, the above are purely family statements. Due to limited personal abilities, there are unavoidable omissions and errors. If bug s are found or there are better suggestions, you are welcome to criticize and correct them with gratitude.
Below is a grey personal blog, which records all the blogs in study and work. Welcome to visit it
- A Grey Blog Personal Blog https://blog.hhui.top
- A Grey Blog-Spring Thematic Blog http://spring.hhui.top