携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情
3.4 事务管理
事务管理常见知识
第一类丢失更新
第二类丢失更新
脏读
不可重复读
幻读
不同的隔离级别可以解决的问题
Spring中的事务管理
Spring中的事务管理有两种方式:
-
声明式事务
-
通过xml配置,声明某方法的事务特征
或
-
通过注解,声明某方法的事务特征
-
-
编程式事务
- 通过 TransactionTemplate 管理事务,并通过它执行数据库的操作。
两者选一种即可,建议选第一种,因为比较简单,当然如果业务比较复杂,仅仅只是想管理一小部分,使用第二种。
写一个demo演示Spring中的事务管理
1. 声明式事务管理事务
这里我们通过加注解声明某方法的事务特征
@Service
public class AlphaService {
@Autowired
private AlphaDao alphaDao;
@Autowired
private UserMapper userMapper;
@Autowired
private DiscussPostMapper discussPostMapper;
/*
isolation 事务的隔离级别
propagation 事务
的传播机制:
REQUIRED: 支持当前事务(外部事务),如果不存在则创建新事务.
REQUIRES_NEW: 创建一个新事务,并且暂停当前事务(外部事务).
NESTED: 如果当前存在事务(外部事务),则嵌套在该事务中执行(独立的提交和回滚),不存在外部事务就会和REQUIRED一样
*/
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public Object save1(){
// 新增用户
User user = new User();
user.setUsername("alpha");
user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
user.setEmail("alpha@qq.com");
user.setHeaderUrl("http://image.nowcoder.com/head/99t.png");
user.setCreateTime(new Date());
userMapper.insertUser(user);
// 新增帖子
DiscussPost post = new DiscussPost();
post.setUserId(user.getId()); // 虽然上面我们没有给user设置id,但是执行过数据库操作之后,数据库给user的id
post.setTitle("Hello");
post.setContent("新人报道!");
post.setCreateTime(new Date());
discussPostMapper.insertDiscussPost(post);
// 报错
Integer.valueOf("abc"); // 将 "abc" 这个字符串转换为整数,肯定转不了,报错
return "ok";
}
}
测试:
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class TransactionTests {
@Autowired
private AlphaService alphaService;
@Test
public void testSave1() {
Object obj = alphaService.save1();
System.out.println(obj);
}
}
2. 编程式事务管理
通过 TransactionTemplate 管理事务
@Service
public class AlphaService {
@Autowired
private AlphaDao alphaDao;
@Autowired
private UserMapper userMapper;
@Autowired
private DiscussPostMapper discussPostMapper;
/*
这个类是Spring自动创建的,我们无须配置,直接注入即可
*/
@Autowired
private TransactionTemplate transactionTemplate;
public Object save2(){
transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); // 设置隔离级别
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); // 设置传播机制
return transactionTemplate.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus status) {
// 新增用户
User user = new User();
user.setUsername("beta");
user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
user.setEmail("beta@qq.com");
user.setHeaderUrl("http://image.nowcoder.com/head/999t.png");
user.setCreateTime(new Date());
userMapper.insertUser(user);
// 新增帖子
DiscussPost post = new DiscussPost();
post.setUserId(user.getId());
post.setTitle("你好");
post.setContent("我是新人!");
post.setCreateTime(new Date());
discussPostMapper.insertDiscussPost(post);
Integer.valueOf("abc");
return "ok";
}
});
}
}
测试:
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class TransactionTests {
@Autowired
private AlphaService alphaService;
@Test
public void testSave2() {
Object obj = alphaService.save2();
System.out.println(obj);
}
}