经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring Boot » 查看文章
SpringBoot超详细讲解事务管理
来源:jb51  时间:2022/8/23 16:19:23  对本文有异议

1. 事务的定义

事务是由 N 步数据库操作序列组成的逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行。

2. 事务的特性

事务的 ACID 特性:

  • 原子性:事务是应用中不可分割的最小执行体
  • 一致性:事务执行的结果必须使得数据从一个一致性状态转变为另一个一致性状态
  • 隔离性:各个事务的执行互不干扰,任何事务的内部操作对其他事务都是隔离的
  • 持久性:事务一旦提交,对数据所做的任何修改都要记录到永久存储器中

3. 事务的隔离性

常见的并发异常

  • 第一类丢失更新、第二类丢失更新
  • 脏读、不可重复读、幻读

常见的隔离级别

  • Read Uncommitted:读取未提交的数据
  • Read Commited:读取已提交的数据
  • Repeatable Read:可重复读
  • Serializable:串行化

第一类更新丢失:某一个事务的回滚,导致另一个事务已更新的数据丢失了。

第二类更新丢失:某一个事务的提交,导致另一个事务已更新的数据丢失了。

脏读:某一个事务,读取了另一个事务未提交的数据。

不可重复读:某一个事务,对同一个数据前后读取的结果不一致。

幻读:某一个事务,对同一个表前后查询到的行数不一致。

隔离级别第一类丢失更新脏读第二类丢失更新不可重复读幻读
Read Uncommitted
Read Commited
Repeatable Read
Repeatable Read

4. 事务管理

实现机制

悲观锁(数据库)

  • 共享锁(S锁):事务A对某数据加了共享锁以后,其他事务只能对该数据加共享锁,但不能加排他锁
  • 排他锁(X锁):事务A对某数据加了排他锁以后,其他事务对该数据既不能加共享锁,也不能加排他锁。

乐观锁(自定义)

  • 版本号、时间戳等
  • 在更新数据前,检查版本号是否发生变化。若发生变化则取消本次更新,否则就更新数据(版本号+1)

Spring 事务管理

声明式事务

  • 通过 XML 配置,声明某方法的事务特征。
  • 通过注解,声明某方法的事务特征。

编程式事务

  • 通过 TransactionTemplate管理事务,并通过它执行数据库的操作。

5. 示例

  1. package com.nowcoder.community.service;
  2. import com.nowcoder.community.dao.AlphaDao;
  3. import com.nowcoder.community.dao.DiscussPostMapper;
  4. import com.nowcoder.community.dao.UserMapper;
  5. import com.nowcoder.community.entity.DiscussPost;
  6. import com.nowcoder.community.entity.User;
  7. import com.nowcoder.community.util.CommunityUtil;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.context.annotation.Scope;
  10. import org.springframework.stereotype.Service;
  11. import org.springframework.transaction.TransactionDefinition;
  12. import org.springframework.transaction.TransactionStatus;
  13. import org.springframework.transaction.annotation.Isolation;
  14. import org.springframework.transaction.annotation.Propagation;
  15. import org.springframework.transaction.annotation.Transactional;
  16. import org.springframework.transaction.support.TransactionCallback;
  17. import org.springframework.transaction.support.TransactionTemplate;
  18. import javax.annotation.PostConstruct;
  19. import javax.annotation.PreDestroy;
  20. import java.util.Date;
  21. @Service
  22. //@Scope("prototype")
  23. public class AlphaService {
  24. @Autowired
  25. private AlphaDao alphaDao;
  26. @Autowired
  27. private UserMapper userMapper;
  28. @Autowired
  29. private DiscussPostMapper discussPostMapper;
  30. @Autowired
  31. private TransactionTemplate transactionTemplate;
  32. public AlphaService() {
  33. // System.out.println("实例化AlphaService");
  34. }
  35. @PostConstruct
  36. public void init() {
  37. // System.out.println("初始化AlphaService");
  38. }
  39. @PreDestroy
  40. public void destroy() {
  41. // System.out.println("销毁AlphaService");
  42. }
  43. public String find() {
  44. return alphaDao.select();
  45. }
  46. // REQUIRED: 支持当前事务(外部事务),如果不存在则创建新事务.
  47. // REQUIRES_NEW: 创建一个新事务,并且暂停当前事务(外部事务).
  48. // NESTED: 如果当前存在事务(外部事务),则嵌套在该事务中执行(独立的提交和回滚),否则就会REQUIRED一样.
  49. @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
  50. public Object save1() {
  51. // 新增用户
  52. User user = new User();
  53. user.setUsername("alpha");
  54. user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
  55. user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
  56. user.setEmail("alpha@qq.com");
  57. user.setHeaderUrl("http://image.nowcoder.com/head/99t.png");
  58. user.setCreateTime(new Date());
  59. userMapper.insertUser(user);
  60. // 新增帖子
  61. DiscussPost post = new DiscussPost();
  62. post.setUserId(user.getId());
  63. post.setTitle("Hello");
  64. post.setContent("新人报道!");
  65. post.setCreateTime(new Date());
  66. discussPostMapper.insertDiscussPost(post);
  67. Integer.valueOf("abc");
  68. return "ok";
  69. }
  70. public Object save2() {
  71. transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
  72. transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
  73. return transactionTemplate.execute(new TransactionCallback<Object>() {
  74. @Override
  75. public Object doInTransaction(TransactionStatus status) {
  76. // 新增用户
  77. User user = new User();
  78. user.setUsername("beta");
  79. user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
  80. user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
  81. user.setEmail("beta@qq.com");
  82. user.setHeaderUrl("http://image.nowcoder.com/head/999t.png");
  83. user.setCreateTime(new Date());
  84. userMapper.insertUser(user);
  85. // 新增帖子
  86. DiscussPost post = new DiscussPost();
  87. post.setUserId(user.getId());
  88. post.setTitle("你好");
  89. post.setContent("我是新人!");
  90. post.setCreateTime(new Date());
  91. discussPostMapper.insertDiscussPost(post);
  92. Integer.valueOf("abc");
  93. return "ok";
  94. }
  95. });
  96. }
  97. }

到此这篇关于SpringBoot超详细讲解事务管理的文章就介绍到这了,更多相关SpringBoot事务管理内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号