# 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
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
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
- 上面添加了两个方法,一个是查询用户,这里我为了不让查询不到的时候报错,所以使用了列表的方式查询。
内容未完......