spring 声明式事务管理在真实的Service和单元测试时的回滚情况,需要注意的问题,jpa为例子

本文详细探讨了Spring声明式事务管理在Service层和单元测试中的回滚情况。通过不同场景的测试,分析了@Transactional与@TransactionConfiguration(defaultRollback=true)的交互作用,以及在真实应用和测试中的事务行为差异。强调了在Spring MVC配置中避免扫描@Service类以保持事务管理特性的重要性,并总结了事务管理的各种特性及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如何测试事务,测试事务回滚情况:

我做了大量的不同的测试:


场景1:   

Service层中使用注解@Transactional,注解@PersistenceContext     private EntityManager  emt;

写了两个方法

     

public	void insertfail()                //插入失败要回滚
{
	
	for(int i=0;i<20;i++)
	{
		User users=new User();
		users.setEmail("sds@qq.com"+i);
		if(i==10)
		{
			int a=1/0;
		}
		this.emt.persist(users);
		
	}
}


public	void insertsuccess()             //正常插入
{
	
	for(int i=0;i<20;i++)
	{
		User users=new User();
		users.setEmail("sds@qq.com"+i);
		
		this.emt.persist(users);
		
	}
}


使用spring-test,junit4进行单元测试

单元测试中不带   @Transactional   和@TransactionConfiguration(defaultRollback=false),然后使用注解激活Service ,写两个测试方法,就是直接调用service的方法

@Autowired
private uservice usv;

	@Test
	public void testshiwu_fail(){
	
	this.usv.insertfail();

	}
	
	@Test
	public void testshiwu_success(){
	
	this.usv.insertsuccess();

	}

最后测试结果:

成功的:
Hibernate: 
    insert 
    into
        User
        (changetime, email, password, registtime, username) 
    values
        (?, ?, ?, ?, ?)
11:48:43.960 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Initiating transaction commit
11:48:43.960 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Committing JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@6d214a1e]
11:48:44.038 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Closing JPA EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@6d214a1e] after transaction
11:48:44.038 [main] DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager

要回滚的:因为出现除以0的错误所以回滚:
Hibernate: 
    insert 
    into
        User
        (changetime, email, password, registtime, username) 
    values
        (?, ?, ?, ?, ?)
11:50:55.662 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Initiating transaction rollback
11:50:55.662 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Rolling back JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@62bb0f89]
11:50:56.416 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Closing JPA EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@62bb0f89] after transaction
11:50:56.416 [main] DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager


这就完结了吗?当然没有:场景一是一个常见的服务层的事务测试。如果我们正确插入,则真的插进数据库了;如果我们运行出现错误,那就回滚了。这是显而易见的。现在我要说的是

场景二:正确插入数据时,也回滚数据,但是我们获取到已经插入的信息,这可以保护数据现场。

@TransactionConfiguration(defaultRollback=true)

第一种:不保护数据现场

Service层代码不变,test中的测试代码也不便,但是在test中加入  @Transactional        @TransactionConfiguration(defaultRollback=false)           //开启事务,并不回滚

测试结果是:

正确插入的方法:
Hibernate: 
    insert 
    into
        User
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值