java 事务嵌套_Java事务以及嵌套事务[通俗易懂]

java 事务嵌套_Java事务以及嵌套事务[通俗易懂]最近遇到事务的处理,嵌套事务,自己研究,整理一下。1先看结论1、在Java事务中,事务的嵌套,如果有事务成功,那么则都成功,否则都不会成功。2、如果事务中存在异常,只要对异常进行捕获和处理,都为执行成功,否则都不会执行成功。2Propagation取值REQUIRED(默认值):在有transaction状态下执行;如当前没有transaction,则创建新的transaction;SUPPO…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

最近遇到事务的处理,嵌套事务,自己研究,整理一下。

1 先看结论

1、在Java事务中,事务的嵌套,如果有事务成功,那么则都成功,否则都不会成功。

2、如果事务中存在异常,只要对异常进行捕获和处理,都为执行成功,否则都不会执行成功。

2 Propagation取值

REQUIRED(默认值):在有transaction状态下执行;如当前没有transaction,则创建新的transaction;

SUPPORTS:如当前有transaction,则在transaction状态下执行;如果当前没有transaction,在无transaction状态下执行;

MANDATORY:必须在有transaction状态下执行,如果当前没有transaction,则抛出异常IllegalTransactionStateException;

REQUIRES_NEW:创建新的transaction并执行;如果当前已有transaction,则将当前transaction挂起;

NOT_SUPPORTED:在无transaction状态下执行;如果当前已有transaction,则将当前transaction挂起;

NEVER:在无transaction状态下执行;如果当前已有transaction,则抛出异常IllegalTransactionStateException。

3 预设场景

这里直接测试spring boot 使用spring data jpa添加一个用户进行测试

实体类user

@Data

@Entity

public class User {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

@Column(name = “id”)

private long id;

private String userName;

public User(String userName) {

this.userName = userName;

}

}

UserRepository类

@Repository

public interface UserRepository extends CrudRepository {

}

UserService类

@Service

public class UserService {

@Autowired

UserRepository userRepository;

测试类

@RunWith(SpringJUnit4ClassRunner.class)

@SpringBootTest

public class UserServiceTest {

@Autowired

UserService userService;

}

4 实际场景使用

4.1 场景:并性事务

并行事务:

A:方法事务为默认的REQUIRED

B:方法事务为 REQUIRES_NEW 或者 REQUIRED

@RunWith(SpringJUnit4ClassRunner.class)

@SpringBootTest

public class UserServiceTest {

@Autowired

UserService userService;

@Test

public void test1() {

userService.addUser1(new User(“user1”));

userService.addUser2(new User(“user2”));

}

}

@Service

public class UserService {

@Autowired

UserRepository userRepository;

@Transactional(rollbackFor = Exception.class)

public void addUser1(User user) {

userRepository.save(user);

}

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)

public void addUser2(User user) {

userRepository.save(user);

throw new RuntimeException();

}

}

执行结果:

保存了user1.

结论:并行事务不存在事务影响

4.2 场景:嵌套相同事务

a) 事务嵌套,在同一个事务中,没有对异常进行处理

@RunWith(SpringJUnit4ClassRunner.class)

@SpringBootTest

public class UserServiceTest {

@Autowired

UserService userService;

@Test

public void test2() {

userService.addUser3();

}

}

@Service

public class UserService {

@Autowired

UserRepository userRepository;

@Transactional(rollbackFor = Exception.class)

public void addUser3() {

userRepository.save(new User(“user3”));

this.addUser4(new User(“user4”));

}

@Transactional(rollbackFor = Exception.class)

public void addUser4(User user) {

userRepository.save(user);

throw new RuntimeException();

}

}

执行结果:两个都没有插入成功

结论:由于两个都是在一个事务当中,所以只要有一个方法事务有问题,那么都不会插入成功。

b) 事务嵌套,在同一个事务中,对异常进行处理

@RunWith(SpringJUnit4ClassRunner.class)

@SpringBootTest

public class UserServiceTest {

@Autowired

UserService userService;

@Test

public void test3() {

userService.addUser5();

}

}

@Service

public class UserService {

@Autowired

UserRepository userRepository;

@Transactional(rollbackFor = Exception.class)

public void addUser5() {

userRepository.save(new User(“user5”));

this.addUser6(new User(“user6”));

}

@Transactional(rollbackFor = Exception.class)

public void addUser6(User user) {

userRepository.save(user);

try {

throw new RuntimeException();

} catch (Exception e) {

e.printStackTrace();

}

}

}

执行结果:两个都插入成功。

结论:如果事务存在异常,并进行捕获处理,不会影响事务。

4.3 场景:嵌套不同事务

a)事务嵌套,在不同事务中,没有对异常进行处理

@RunWith(SpringJUnit4ClassRunner.class)

@SpringBootTest

public class UserServiceTest {

@Autowired

UserService userService;

@Test

public void test4() {

userService.addUser7();

}

}

@Service

public class UserService {

@Autowired

UserRepository userRepository;

@Transactional(rollbackFor = Exception.class)

public void addUser7() {

userRepository.save(new User(“user7”));

this.addUser8(new User(“user8”));

}

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)

public void addUser8(User user) {

userRepository.save(user);

throw new RuntimeException();

}

}

执行结果:都没有插入成功。

结论:不同事务中,嵌套的事务,没有对异常进行处理,都不会执行成功。(其实在外部事务中出错,两个也是都不会插入成功数据。)

b)事务嵌套,在不同事务中,对异常进行处理

@RunWith(SpringJUnit4ClassRunner.class)

@SpringBootTest

public class UserServiceTest {

@Autowired

UserService userService;

@Test

public void test5() {

userService.addUser9();

}

}

@Service

public class UserService {

@Autowired

UserRepository userRepository;

@Transactional(rollbackFor = Exception.class)

public void addUser9() {

userRepository.save(new User(“user9”));

this.addUser10(new User(“user10”));

}

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)

public void addUser10(User user) {

userRepository.save(user);

try {

throw new RuntimeException();

} catch (Exception e) {

e.printStackTrace();

}

}

}

执行结果:都插入成功。

结论:不同事务,只要对异常进行捕获并处理,都会执行成功

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • jQuery插件库常用前端库引用地址详细提供

    jQuery插件库常用前端库引用地址详细提供摘要 为了节省大家查找前端库引用地址耗费的时间 在这里为大家整理了 jQuery jquery migrate jQueryUI bootstrap reset css font awesome three html5 js angular animate vue ECharts 的引用地址 常用前端地址 jQuery scriptsrc https www jq22 com jquery jquery 3 3 1 js scriptsrc https

    2025年12月15日
    6
  • 面试JAVA常被问到的问题(持续更新中)

    面试JAVA常被问到的问题(持续更新中)引言有的面试会被问到有没有写博客,这时候我尴尬,不知道怎么回答,所以这篇文章仅仅是把我面试JAVA的遇到的问题记录下来而已,也算是我写博客迈出的第一步,起码,以后被问到:有没有写博客?我可以回答,我写过。 (最主要的是以后换工作我不用频繁百度常见面试题了。。。。)ps1,别把我太当回事,我是个LJ;2,说得不对的地方请多多包涵,想看更详细的请百度官方文档和其他大佬的文章;3,如果有被问到…

    2022年7月9日
    24
  • pychram2021.12激活【2021.10最新】

    (pychram2021.12激活)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html41MD9IQHZL-eyJsa…

    2022年3月30日
    54
  • git学习——设置gitlab、github默认push的用户名和密码

    在使用git的时候,不同的环境下,当你重新安装git,最好在开始的时候就配置一下默认的git的用户名和密码,这样子就可以在每次的push的时候不需要手动的在去输入git的用户名和密码,提高执行的效率。 环境:Windows环境已经安装git,我使用的gitlab(github和这样配一样),gitlab的用户名742981086@qq.com 下面在Windows环境中进行配置过程的演示, 1

    2022年2月25日
    324
  • html Window与document区别

    html Window与document区别Window–代表浏览器中一个打开的窗口:对象属性  window//窗口自身  window.self//引用本窗户window=window.self  window.name//为窗口命名  window.defaultStatus//设定窗户状态栏信息  window.location//URL地址,配备布置这个属性可以打开新的页面对象方法  window.alert("t…

    2022年7月19日
    18
  • java 静态变量 存储_java中,类的静态变量如果是对象,该对象将存储在内存的哪个区域?…

    java 静态变量 存储_java中,类的静态变量如果是对象,该对象将存储在内存的哪个区域?…静态变量所引用的实例位于Java堆或运行时常量池。Java字节码与Native机器码不同,字节码是运行在JVM这一平台上的,字节码在被解释的过程中,具体的执行方式因JVM的不同实现而不同,但是对于JVM来说,它的各种不同实现都必须要遵循Java虚拟机规范。JVM的运行时数据区包含以下部分:1、PC寄存器每一条Java虚拟机线程都有自己的PC寄存器,如果正在被线程执行的当前方法不是native的,那…

    2022年4月28日
    48

发表回复

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

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