目录
一、事务简介
二、准备数据库
三、创建maven项目,引入依赖和完成相关配置
1. pom.xml文件
2. 创建配置文件
四、编写Java代码
1. Account实体类
2. AccountDao接口
3. AccountService业务类
五、测试
1. 测试方法
2. 测试结果编辑
往期专栏&文章相关导读
1. Maven系列专栏文章
2. Mybatis系列专栏文章
3. Spring系列专栏文章
一、事务简介
二、准备数据库
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for account
-- ----------------------------
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`balance` double NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of account
-- ----------------------------
INSERT INTO `account` VALUES (1, '张三', 1000);
INSERT INTO `account` VALUES (2, '李四', 1000);
SET FOREIGN_KEY_CHECKS = 1;
三、创建maven项目,引入依赖和完成相关配置
1. pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>spring_transfer</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.1.1</version>
</dependency>
<!-- mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<!-- druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.13</version>
</dependency>
<!-- MyBatis与Spring的整合包,该包可以让Spring创建MyBatis的对象 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.13</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
<!-- junit,如果Spring5整合junit,则junit版本至少在4.12以上 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- spring整合测试模块 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.13</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2. 创建配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:http="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 包扫描 -->
<context:component-scan base-package="com.example"/>
<!-- 创建druid数据源对象 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring"/>
<property name="username" value="root"/>
<property name="password" value="666666"/>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.dao"/>
</bean>
</beans>
四、编写Java代码
1. Account实体类
package com.example.pojo;
public class Account {
// 账号
private int id;
// 用户名
private String username;
// 余额
private double balance;
public Account() {
}
public Account(int id, String username, double balance) {
this.id = id;
this.username = username;
this.balance = balance;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
@Override
public String toString() {
return "Account[ " +
"id=" + id +
", username='" + username + '\'' +
", balance=" + balance +
" ]";
}
}
2. AccountDao接口
package com.example.dao;
import com.example.pojo.Account;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;
@Repository
public interface AccountDao {
// 根据id查找用户
@Select("select * from account where id=#{id}")
Account findById(int id);
// 修改用户
@Update("update account set balance = #{balance} where id = #{id}")
void update(Account account);
}
3. AccountService业务类
package com.example.service;
import com.example.dao.AccountDao;
import com.example.pojo.Account;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AccountService {
@Autowired
private AccountDao accountDao;
/**
*
* @param id1 转出人id
* @param id2 转入人id
* @param price 金额
*/
// 作用方法上时,该方法都将具有该类型事务的事务属性
public void transfer(int id1,int id2, double price){
// 转出人减少余额
Account account1 = accountDao.findById(id1);
account1.setBalance(account1.getBalance() - price);
accountDao.update(account1);
// 模拟程序出错
int i = 1 / 0;
// 转入人增加余额
Account account2 = accountDao.findById(id2);
account2.setBalance(account2.getBalance() + price);
accountDao.update(account2);
}
}
五、测试
1. 测试方法
import com.example.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class AccountServiceTest {
@Autowired
private AccountService accountService;
@Test
public void testTransfer(){
accountService.transfer(1,2,500);
}
}
2. 测试结果

往期专栏&文章相关导读
1. Maven系列专栏文章
Maven系列专栏 | Maven工程开发 |
Maven聚合开发【实例详解---5555字】 |
2. Mybatis系列专栏文章
Mybatis系列专栏 | MyBatis入门配置 |
Mybatis入门案例【超详细】 |
MyBatis配置文件 —— 相关标签详解 |
Mybatis模糊查询——三种定义参数方法和聚合查询、主键回填 |
Mybatis动态SQL查询 --(附实战案例--8888个字--88质量分) |
Mybatis分页查询——四种传参方式 |
Mybatis一级缓存和二级缓存(带测试方法) |
Mybatis分解式查询 |
Mybatis关联查询【附实战案例】 |
MyBatis注解开发---实现增删查改和动态SQL |
MyBatis注解开发---实现自定义映射关系和关联查询 |
3. Spring系列专栏文章
Spring系列专栏 | Spring IOC 入门简介【自定义容器实例】 |
IOC使用Spring实现附实例详解 |
Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式 |
Spring DI简介及依赖注入方式和依赖注入类型 |
Spring IOC相关注解运用——上篇 |
Spring IOC相关注解运用——下篇 |
Spring AOP简介及相关案例 |
注解、原生Spring、SchemaBased三种方式实现AOP【附详细案例】 |
Spring事务简介及相关案例 |
Spring 事务管理方案和事务管理器及事务控制的API |
Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务 |