# Spring教程 - 11 注解方式实现声明式事务

事务是一组数据库操作的集合,这些操作要么 全部成功,要么 全部失败

例如张三给李四转账100,要张三的账户减去100,李四的账户加上100,这是一组操作,必须全部成功,不能张三账户减去100成功,李四账户加上100失败,这会导致数据错误。

在前面介绍 JdbcTemplate 的时候,我们是没有处理事务的,默认情况下每条 SQL 都是一个单独的事务(即自动提交模式,autoCommit=true)。你执行一条更新的 SQL,它会立即提交到数据库。

关于事务的知识,可以查看 SQL 教程 - 事务 (opens new window)


下面就来模拟一下张三给李四转账100的操作。

# 11.1 不处理事务

我们还是按照 Controller --> Service --> Dao 的方式,分层调用来实现。

# 1 实现Dao

接口:IUserDao.java

添加两个方法,一个是查询用户,一个是修改用户的余额。

package com.foooor.hellospring.dao;

import com.foooor.hellospring.pojo.User;

public interface IUserDao {
     /**
      * 根据id查询用户
      */
     User selectById(int userId);

     /**
      * 修改用户余额
      */
     void updateBalance(int userId, int balance);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

实现类:UserDaoImpl.java

记得添加注解。

package com.foooor.hellospring.dao.impl;

import com.foooor.hellospring.dao.IUserDao;
import com.foooor.hellospring.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class UserDaoImpl implements IUserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 根据id获取用户
     */
     @Override
     public User selectById(int userId) {
        // 1.准备sql
        String sql = "select balance from tb_user where id = ?";
        // 2.执行查询
        List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class), userId);
        // 3.返回结果
        return userList.isEmpty() ? null : userList.get(0);
     }

    /**
     * 修改用户余额
     */
     public void updateBalance(int userId, int balance) {
        // 1.准备sql
        String sql = "update tb_user set balance = balance + ? where id = ?";
        // 2.执行更新
        jdbcTemplate.update(sql, balance, userId);
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  • 上面添加了两个方法,一个是查询用户,这里我为了不让查询不到的时候报错,所以使用了列表的方式查询。
内容未完......