这篇文章主要介绍“SpringBoot事务管理实例分析”,在日常操作中,相信很多人在SpringBoot事务管理实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SpringBoot事务管理实例分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
事务是由 N 步数据库操作序列组成的逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行。
事务的 ACID
特性:
原子性:事务是应用中不可分割的最小执行体
一致性:事务执行的结果必须使得数据从一个一致性状态转变为另一个一致性状态
隔离性:各个事务的执行互不干扰,任何事务的内部操作对其他事务都是隔离的
持久性:事务一旦提交,对数据所做的任何修改都要记录到永久存储器中
常见的并发异常
第一类丢失更新、第二类丢失更新
脏读、不可重复读、幻读
常见的隔离级别
Read Uncommitted:读取未提交的数据
Read Commited:读取已提交的数据
Repeatable Read:可重复读
Serializable:串行化
第一类更新丢失:某一个事务的回滚,导致另一个事务已更新的数据丢失了。
第二类更新丢失:某一个事务的提交,导致另一个事务已更新的数据丢失了。
脏读:某一个事务,读取了另一个事务未提交的数据。
不可重复读:某一个事务,对同一个数据前后读取的结果不一致。
幻读:某一个事务,对同一个表前后查询到的行数不一致。
隔离级别 | 第一类丢失更新 | 脏读 | 第二类丢失更新 | 不可重复读 | 幻读 |
---|---|---|---|---|---|
Read Uncommitted | 是 | 是 | 是 | 是 | 是 |
Read Commited | 否 | 否 | 是 | 是 | 是 |
Repeatable Read | 否 | 否 | 否 | 否 | 是 |
Repeatable Read | 否 | 否 | 否 | 否 | 否 |
实现机制
悲观锁(数据库)
共享锁(S锁):事务A对某数据加了共享锁以后,其他事务只能对该数据加共享锁,但不能加排他锁
排他锁(X锁):事务A对某数据加了排他锁以后,其他事务对该数据既不能加共享锁,也不能加排他锁。
乐观锁(自定义)
版本号、时间戳等
在更新数据前,检查版本号是否发生变化。若发生变化则取消本次更新,否则就更新数据(版本号+1)
Spring 事务管理
声明式事务
通过 XML 配置,声明某方法的事务特征。
通过注解,声明某方法的事务特征。
编程式事务
通过 TransactionTemplate管理事务,并通过它执行数据库的操作。
package com.nowcoder.community.service; import com.nowcoder.community.dao.AlphaDao; import com.nowcoder.community.dao.DiscussPostMapper; import com.nowcoder.community.dao.UserMapper; import com.nowcoder.community.entity.DiscussPost; import com.nowcoder.community.entity.User; import com.nowcoder.community.util.CommunityUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.Date; @Service //@Scope("prototype") public class AlphaService { @Autowired private AlphaDao alphaDao; @Autowired private UserMapper userMapper; @Autowired private DiscussPostMapper discussPostMapper; @Autowired private TransactionTemplate transactionTemplate; public AlphaService() { // System.out.println("实例化AlphaService"); } @PostConstruct public void init() { // System.out.println("初始化AlphaService"); } @PreDestroy public void destroy() { // System.out.println("销毁AlphaService"); } public String find() { return alphaDao.select(); } // 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("https://cache.yisu.com/upload/information/20220823/112/6198.png"); user.setCreateTime(new Date()); userMapper.insertUser(user); // 新增帖子 DiscussPost post = new DiscussPost(); post.setUserId(user.getId()); post.setTitle("Hello"); post.setContent("新人报道!"); post.setCreateTime(new Date()); discussPostMapper.insertDiscussPost(post); Integer.valueOf("abc"); return "ok"; } 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("https://cache.yisu.com/upload/information/20220823/112/6199.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"; } }); } }
到此,关于“SpringBoot事务管理实例分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。