电脑
intelliJ idea,jdk1.8,mysql
上一篇讲解了创建spring+mybatis的项目,现在在之前的基础上加入service层的事务控制。
在service层加入事务控制是非常重要的一个环节,项目难免会出现一些bug,可能因为逻辑判断不到位导致的异常,可能是数据填写的不正确导致的异常等等情况,导致前面添加数据添加或修改成功而后面的数据添加或修改失败。 举个例子:有个业务包含表1和表2,表1和表2存在关联关系,业务的服务层分别进行表1和表2的数据添加,表1先开始添加一条,执行成功后,执行表2的时候出现逻辑异常,表2的数据添加不了,这时就存在一表添加成功一表没添加成功的情况,如果执行多次表1会重复添加多条数据,这是不允许的,要么一起成功要么一起失败。
这个时候在service层添加事务是非常有必要的。不过service层的统一事务控制非常简单。只需在方法上面加个注释@Transactional就可以了。@Transactional是Spring集成专门用来管理事务的。
这次引用的是之前的model和dao,修改service层和测试代码: service层代码: import cn.cy.dao.SysUserDaoInter; import cn.cy.model.SysUser; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource;@Service public class SysUserService { @Resource private SysUserDaoInter sysUserDaoInter; public boolean addSysUser(SysUser sysUser) { return sysUserDaoInter.addSysUser(sysUser)>0?true:false; } @Transactional public boolean addTwoSysUser(SysUser user1, SysUser user2) { boolean bool1 = sysUserDaoInter.addSysUser(user1)>0?true:false; if (true) { throw new RuntimeException('逻辑异常了!'); } boolean bool2 = sysUserDaoInter.addSysUser(user2)>0?true:false; return bool1&&bool2; } }
测试代码为: import cn.cy.model.SysUser; import cn.cy.service.SysUserService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; @RunWith(SpringRunner.class) @SpringBootTest public class SpringbootProjectApplicationTests { @Resource private SysUserService sysUserService; @Test public void add() { SysUser sysUser = new SysUser(); sysUser.setAge(12); sysUser.setId(1); sysUser.setName('zhangsan'); sysUser.setPsw('qwer'); System.out.println(sysUserService.addSysUser(sysUser)); } @Test public void addTwo() { SysUser sysUser1 = new SysUser(); sysUser1.setAge(3); sysUser1.setId(3); sysUser1.setName('小米'); sysUser1.setPsw('qwer'); SysUser sysUser2 = new SysUser(); sysUser2.setAge(4); sysUser2.setId(4); sysUser2.setName('大米'); sysUser2.setPsw('qwer'); System.out.println(sysUserService.addTwoSysUser(sysUser1, sysUser2)); } }
结果出现了异常并且数据库中没有添加sysUser1 的数据,如下图:
如果没加@Transactional注释,数据库的结果会是下图的结果。
@Transactional的关键注意点:由于@Transactional在Spring中的默认的事务规则是遇到运行异常(RuntimeException)才会进行回滚。如果想针对特殊异常进行事务回滚,可以在@Transactional 注解里使用rollbackFor 属性明确指定异常。比如:@Transactional(rollbackFor= Exception.class)这种写法。