Spring事务隔离级别与设置

Spring事务隔离级别与设置我们都知道数据库隔离级别有 4 中 分别为读未提交 读已提交 可重复读 串行化 其实 Spring 也可以设置数据库隔离级别 Spring 事务隔离级别比数据库事务隔离级别多一个 default1 DEFAULT 默认 这是一个 PlatfromTran 默认的隔离级别 使用数据库默认的事务隔离级别 另外四个与 JDBC 的隔离级别相对应 2 READ UNCOMMITTED 读未提交 这是事务最低的隔离级别 它允许另外一个事务可以看到这个事务未提交的数据 这种隔离级别会产生

我们都知道数据库隔离级别有4种,分别为读未提交、读已提交、可重复读、串行化。其实Spring也可以设置数据库隔离级别。

Spring事务隔离级别比数据库事务隔离级别多一个default

1) DEFAULT (默认)
这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应。

2) READ_UNCOMMITTED (读未提交)
这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻读。

3) READ_COMMITTED (读已提交)
保证一个事务修改的数据提交后才能被另外一个事务读取,另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻读。

4) REPEATABLE_READ (可重复读)
这种事务隔离级别可以防止脏读、不可重复读,但是可能出现幻读(mysql已经通过采用next-key锁解决了幻读问题)。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了不可重复读。

5) SERIALIZABLE(串行化)
这是花费最高代价但是最可靠的事务隔离级别,事务被处理为顺序执行。除了防止脏读、不可重复读外,还避免了幻读。


























Spring的@Transactional注解的isolation属性可以设置隔离级别,它提供了以下枚举对应各个隔离级别

public enum Isolation { DEFAULT(-1), READ_UNCOMMITTED(1), READ_COMMITTED(2), REPEATABLE_READ(4), SERIALIZABLE(8); private final int value; private Isolation(int value) { this.value = value; } public int value() { return this.value; } }

下面我们通过代码来验证下

import com.wpw.group.springstudy.sql.User; import com.wpw.group.springstudy.sql.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Service public class TransactionService { @Autowired private UserMapper userMapper; //由于 @Transactional 采用的是代理模式,采用this调用不会生效,所以这里通过自引用的方式来调用。 @Autowired private TransactionService transactionService; / * 由于远程调用的是 方法是读未提交的,所以会返回数据 * @return */ @Transactional public User readUncommitIsolation() { User user = new User(); user.setName("name"); user.setSex("sex"); userMapper.insertSelective(user); return transactionService.getReadUncommit(user.getId()); } / * 采用的是读未提交隔离级别,调用这个方法的会读取到未提交的事务 * @param id * @return */ @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED) public User getReadUncommit(Long id) { return userMapper.selectByPrimaryKey(id); } / * 远程调用的是 默认隔离级别的方法,即可重复读,因此此处会返回null * @return */ @Transactional public User defaultIsolation() { User user = new User(); user.setName("name"); user.setSex("sex"); userMapper.insertSelective(user); return transactionService.getDefault(user.getId()); } / * 未配置隔离级别,会使用默认隔离级别,即数据库默认的事务隔离级别,mysql的默认的隔离级别是 可重复读,所以调用这个方法不会返回数据 * @param id * @return */ @Transactional(propagation = Propagation.REQUIRES_NEW) public User getDefault(Long id) { return userMapper.selectByPrimaryKey(id); } }

如上代码中,我在入口方法readUncommitIsolation()和defaultIsolation()中,都插入了一条数据,之后调用不同隔离级别的方法来获取这条数据。readUncommitIsolation()调用的是isolation = Isolation.READ_UNCOMMITTED即读未提交隔离级别的方法,defaultIsolation()调用的是没有配置隔离级别的方法,即会采用我的mysql默认的隔离级别。需要注意的是,为了新开一个事务进行查询,我将两个查询的方法的传播级别都设置成了propagation = Propagation.REQUIRES_NEW,来重新开启一个事务。

通过Controller来调用service的方法:

@RestController @RequestMapping("/tr") public class TransactionController { @Autowired private TransactionService transactionService; @GetMapping("/readUnIsolation") public User readUn() { return transactionService.readUncommitIsolation(); } @GetMapping("/defaultIsolation") public User defaultIsolation() { return transactionService.defaultIsolation(); } }

启动程序后

请求:http://127.0.0.1:8080/tr/readUnIsolation ,即会调用未提交隔离级别的查询,每次都会返回插入的数据

请求:http://127.0.0.1:8080/tr/defaultIsolation 即会调用默认隔离级别的查询,不会返回数据

由此可见,Spring事务隔离级别与MySQL设置的级别不一样时,Spring的隔离级别生效

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/177299.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午7:50
下一篇 2026年3月26日 下午7:50


相关推荐

  • android四种启动模式_android:windowSoftInputMode

    android四种启动模式_android:windowSoftInputMode(1)添加头文件:#include(2)在特定驱动结构体中添加early_suspend结构:#ifdefCONFIG_HAS_EARLYSUSPENDstructearly_suspendearly_suspend;#endif(3)在驱动probe函数中注册相关early_suspend结构体:#ifdefCONFIG_HAS_EARLYSUSPEND

    2026年1月18日
    4
  • 静态网站(博客)生成器Static Site Generators(SSGs)大集合

    静态网站(博客)生成器Static Site Generators(SSGs)大集合这是一份静态网站生成器的推荐集合,按开发语言或者平台分类和排序,大家各取所需。如果大家有用什么新的静态网站生成器未在本文章中列出,麻烦在评论中说下,我会不断更新该集合。ClojureCryogen-Asimple,static,automatedCMSshippedasatemplateonLeiningen,aClojurebuildtool.misak…

    2022年7月11日
    21
  • 命令行工具箱:常用命令速查、脚本生成、效率提升

    命令行工具箱:常用命令速查、脚本生成、效率提升

    2026年3月13日
    1
  • ParameterizedThreadStart 实例化[通俗易懂]

    ParameterizedThreadStart 实例化[通俗易懂]C#之线程ParameterizedThreadStart今天用到了ParameterizedThreadStart的实例化对象,但是总提示没有与委托匹配的重载,网上搜索了很多,终于明白什么原因了,再次记录下方便以后查阅。classProgram{staticvoidMain(string[]args){Workwork=newWork();//两种实…

    2022年7月15日
    19
  • 进入mysql_怎么用cmd进入mysql

    进入mysql_怎么用cmd进入mysql如何使用CMD命令行进入MySQL数据库?下面就和小编一起学习一下如何操作吧。具体步骤:1、打开【开始】》【运行】输入【cmd】单击【确定】后出现CMD命令黑色窗口,这就是我们说的CMD命令行,或者使用快捷键Windows键(在键盘上有个Windows标志的按键)+R输入cmd后回车。2、在CMD命令窗口敲入命令后按回车即可进入MySQL。mysql-hlocalhost-uroot-p(注…

    2022年6月11日
    54
  • 基于xxx的系统实现「建议收藏」

    基于xxx的系统实现「建议收藏」帮助解答任何系统问题1.成品:看最下面2.基于强化学习的Tic-Tac-To实现3.基于文本的关键词打标4.基于自然语言处理的情感分析系统5.基于深度学习的语音识别系统6.基于深度学习的人脸识别系统7.随机森林的多分类问题研究8.回归算法预测系统9.决策树算法的分类系统10.基于Python的lstm情感分析11.基于Python的金融分析系统12.基于Python的电商评论爬虫系统13.基于Flask的校园课程管理系统设计与实现14.基于Flask的人脸识别企业系统15.vb

    2025年12月10日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号