JDBC下的事务
在这里,直接模拟一个账户表。我们在账户存钱,存钱的先后顺序会有一些逻辑处理,假设我们已经对数据库中插入了数据,但之后出现了异常,需要将存在账户中的数据回滚。在开始程序之前,新建一个 jdbcTransaction 包,具体如图7.4所示。

Figure 1. 图7.4 程序结构
首先,需要新建 ACCOUNT 表,在表中加入一些数据,这些数据主要是用来和执行效果对比,SQL 如下所示。
CREATE TABLE ACCOUNT(
ID INT(16) NOT NULL,
MONEY DECIMAL(10,2),
PRIMARY KEY(ID)
);
INSERT INTO ACCOUNT VALUE(1,999.99);
INSERT INTO ACCOUNT VALUE(2,999.99);
INSERT INTO ACCOUNT VALUE(3,999.99);
然后,针对表新建实体类,代码如下所示。
package com.springBoot.jdbcTransaction.entiry;
import java.math.BigDecimal;
public class Account {
private int id;
private BigDecimal money;
//set and get
.
}
接着写 Mapper 接口,其功能主要是用来实现数据库表的更新操作。访问为 save 方法,这里的 SQL 直接写在注解里,没有另外写 XML。代码如下所示。
package com.springBoot.jdbcTransaction.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Update;
@Mapper
public interface AccountMapper {
@Update("update account set money=money+1000 where id=2")
public void save();
}
然后,在写完数据访问层的代码之后,在此基础上,写 AccountService 类,代码如下所示。
package com.springBoot.jdbcTransaction.service;
@Service
public class AccountService {
@Autowired
AccountMapper accountMapper;
@Transactional
public void save(){
accountMapper.save();
throw new RuntimeException("=====异常=====");
}
}
上面的代码中,可以看到在 save 方法上有一个注解 @Transactional,其作用在前面已介绍,这个方法将会存在事务操作。在这个方法中,先对数据库进行更新操作,更新之后,模拟业务上出现业务异常,这个异常将会在上层业务中继续处理。
然后,开始写我们的业务控制层,代码如下所示。
package com.springBoot.jdbcTransaction.controller;
@RestController
public class AccountController {
@Autowired
AccountService accountService;
@RequestMapping(value = "/save",method = RequestMethod.GET)
public Object save(){
try{
accountService.save();
}catch (Exception ex){
return "异常了";
}
return "success";
}
}
在上面的代码中,会进行数据的更新,同时会捕获底层出现的异常,异常捕获主要来源于 AccountService。最后,我们使用 Restful 测试的方式对事务进行测试,所以还需要一个启动类,启动类的代码如下所示。
package com.springBoot.jdbcTransaction;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
程序启动后,在页面上访问 http://localhost:8082/save?id=5&money=666.77 (地址栏默认省略“http://”)。执行效果如图7.5所示。

Figure 2. 图7.5 执行效果
这时需要看数据的执行情况,如图7.6所示。

Figure 3. 图7.6 数据库的执行情况