SSM-如何验证事务是否生效

spring配置事务的三种方式:编程式、声明式、注解式

1、配置事务

要实现注解式的事务配置,只需在applicationContext.xml中加入如下代码:

<!-- 配置事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />

只需在业务层中添加@Transaction方法即可使用事务

@Transaction

只能用到 public 方法上,对于其他非 public 方法,标记了 @Transaction 也不会报错,但方法没有事务功能
<!-- mybatis.spring自动映射,会扫描org.mybatis.spring.sample.mapper下的所有接口,然后创建各自接口的动态代理类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.mycompany.web.entity.mapping"/>
</bean>

<!-- 自动扫描,多个包以 逗号分隔,让Bean定义注解工作起来 -->
<context:component-scan base-package="com.mycompany.web"/>
<aop:aspectj-autoproxy proxy-target-class="true"/>
如果此时报错,是因为文件头没有引入xmlns和schema导致的,在文件头引入即可,只需引入需要的

2、单个事务测试场景:

插入一个User对象的集合,如果插入对象的个数小于2,则正常插入;如果试图插入5条数据(对象的个数大于2),则抛出异常(事务必处理必须抛出异常,只有这样,spring才能帮助事务回滚),这样,数据库就会回滚,不插入任何数据。测试结果,如果数据库没插入任何数据,证明事务处理设置成功,否则,失败。

测试业务类方法的代码如下:

@Service("userService")
public class UserServiceImpl implements IUserService{
	
	@Resource
	private IUserDao userDaoImpl;	

	@Transactional
	@Override
	publicvoid Amethod(List<User> userList){
		for(int i=0;i<userList.size();i++){
			if(i<<span style="color:#ff0000;background-color: rgb(255, 255, 255);">2</span>){
				this.userDaoImpl.insert(userList.get(i));
			}else{
				thrownew RuntimeException();
			}
		}
	}
}

由于单元测试没有成功,将测试代码放入Controller方法中,走页面跳转:

@RequestMapping("/index")
public String getUserById(Model model){
	    
	    List<User> userList = new ArrayList<User>();
	    for(int i=0;i<5;i++){
	    	User userTemp = new User();
	    	userTemp.setId(i+2L);
	    	userTemp.setAge(i);
	    	userTemp.setName("xiaohong" + i);
	    	userTemp.setGender("女");
	    	userList.add(userTemp);
	    }
	    userService.insertUser(userList);
	    
        return "MyJsp";
    }

运行成功后打开访问页面, 会出现错误,因为方法中抛出了这个异常。实质上是进行了事务管理,数据库没有插入数据,表示事务配置成功;反之,如果方法上去掉 @Transaction ,则前两条数据会插入到数据库中,然后报异常。

参考出处忘记了。


3、多个事务测试场景:

场景一:在2的基础上再加一个实体UserRole,同样的方式测试业务类中加入方法:

@Transactional
@Override
public void Bmethod(List<UserRole> userRoleList){
<span style="white-space:pre">	</span>for(int i=0;i<userRoleList.size();i++){
	<span style="white-space:pre">	</span>if(i<<span style="color:#ff0000;">2</span>){
<span style="white-space:pre">			</span>this.userRoleDaoImpl.insertSelective(userRoleList.get(i));
		}else{
		<span style="white-space:pre">	</span>throw new RuntimeException();
		}
	}
}
在Controller类的方法getUserById中加入如下代码:

List<UserRole> userRoleList = new ArrayList<UserRole>();
	    for(int i=0;i<5;i++){
	    	UserRole userRoleTemp = new UserRole();
	    	userRoleTemp.setRoleId(i+1L);
	    	userRoleTemp.setUserId(i+1L);
	    	userRoleTemp.setCreateUserId(i+1L);
	    	userRoleTemp.setCreateTime(new Date());
	    	userRoleList.add(userRoleTemp);
	    }
	    userRoleService.insertUserRole(userRoleList);
运行后,发现两个事务是单独生效并且都生效的


场景二:那么再修改一下,在Amethod中调用Bmethod方法,
在controller中调用A方法,问:此时生效的事务是A还是B还是A和B的事务都生效?

结果:

1)当A、B都满足条件时(即条件为插入数据小于2条,而试图插入的数据个数也小于2条),才成功保存数据并且全部数据都成功保存;

2)当A不满足条件或B不满足条件或A和B都不满足条件时,全部回滚,所有数据都保存失败,并抛出异常。



你可能感兴趣的:(spring,事务)