SSM项目中添加事务

事务分为声明式事务和编程式事务,在这里我们主要说明声明式事务,声明式事务的使用方法在Spring的著配置文件中添加配置

  //配置事务
  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  //添加数据库
        <property name="dataSource" ref="dataSource"/>
     </bean>
     //开启事务注解
    <tx:annotation-driven transaction-manager="transactionManager"/>

紧接着只需要在你认为需要添加业务的方法上添加注解@Transactional 需要注意的时@Transactional只能加到public方法上才会生效

需要注意的时事务在使用的时候默认RuntimeException时运行时异常回滚,Exceptio提交,所以你在使用的时候需要注意了,如说你在添加@Transactional注解的方法中把异常给捕获也就是try…catchl了,那么这时候回滚还是提交就要看你catch中抛出的是什么异常,实例如下

1. catch中抛出运行时异常
 @Override
    @Transactional
    public void addUser() {
        try {
            User user = new User();
            user.setId("35");
            user.setUsername("12345");
            user.setPassword("132456");
            userMapper.insertUser(user);

            User user1 = new User();
            user1.setId("36");
            user1.setUsername("12345");
            user1.setPassword("132456");
            userMapper.insertUser(user1);

            User user2 = new User();
            user2.setId("37");
            user2.setUsername("12345");
            user2.setPassword("132456");
            userMapper.insertUser(user2);

            User user3 = new User();
            user3.setUsername("12345");
            user3.setPassword("132456");
            userMapper.insertUser(user3);
        }
        catch (Exception e){
            throw new RuntimeException();
        }


    }

在上面的代码中我故意不给第四个的User对象的id属性赋值,而在数据库中id又是不允许为空的所以就报错了

在这里插入图片描述

但是可以看到我的数据库表中并没有因为最后一个出而添加前面的,可以看到表中并没有代码中的设置的几个id

在这里插入图片描述

2catch中抛出IllegalAccessException(这个异常属于Exception的子类也就是不属于运行时异常)
  @Override
    @Transactional
    public void addUser() throws IllegalAccessException {
        try {
            User user = new User();
            user.setId("35");
            user.setUsername("12345");
            user.setPassword("132456");
            userMapper.insertUser(user);

            User user1 = new User();
            user1.setId("36");
            user1.setUsername("12345");
            user1.setPassword("132456");
            userMapper.insertUser(user1);

            User user2 = new User();
            user2.setId("37");
            user2.setUsername("12345");
            user2.setPassword("132456");
            userMapper.insertUser(user2);

            User user3 = new User();
            user3.setUsername("12345");
            user3.setPassword("132456");
            userMapper.insertUser(user3);
        }
        catch (Exception e){
            throw new IllegalAccessException();
        }
    }

执行结果以及数据库表
在这里插入图片描述

在这里插入图片描述

可以看到上面的程序虽然出错了但是数据库表还是进行的新增操作,并没有回滚事务而是进行了提交

接下是不使用try…catch捕获异常,而是使用throw直接抛出异常

1.抛出IllegalAccessException 异常
  @Override
    @Transactional
    public void addUser() throws IllegalAccessException {

        User user = new User();
        user.setId("38");
        user.setUsername("12345");
        user.setPassword("132456");
        userMapper.insertUser(user);

        User user1 = new User();
        user1.setId("39");
        user1.setUsername("12345");
        user1.setPassword("132456");
        userMapper.insertUser(user1);

        User user2 = new User();
        user2.setId("40");
        user2.setUsername("12345");
        user2.setPassword("132456");
        userMapper.insertUser(user2);

        User user3 = new User();
        user3.setUsername("12345");
        user3.setPassword("132456");
        int i = userMapper.insertUser(user3);
        if (i != 1) {

            throw new IllegalAccessException();
        }
    }

在上面的执行结果中我让最后一个插入返回一下插入结果进行一下判断如果不满意抛出异常,学习过的都知道这个必然是错误的

执行结果和数据库截图如下

在这里插入图片描述

在这里插入图片描述

可以看到上面的数据库表中并没有因为出错而新增的数据,说明进行了事务的回滚

2.抛出运行时异常
 @Override
    @Transactional
    public void addUser(){

        User user = new User();
        user.setId("38");
        user.setUsername("12345");
        user.setPassword("132456");
        userMapper.insertUser(user);

        User user1 = new User();
        user1.setId("39");
        user1.setUsername("12345");
        user1.setPassword("132456");
        userMapper.insertUser(user1);

        User user2 = new User();
        user2.setId("40");
        user2.setUsername("12345");
        user2.setPassword("132456");
        userMapper.insertUser(user2);

        User user3 = new User();
        user3.setUsername("12345");
        user3.setPassword("132456");
        int i = userMapper.insertUser(user3);
        if (i != 1) {

            throw new RuntimeException();
        }
    }

执行结果和数据库结果如下

在这里插入图片描述
在这里插入图片描述

结论就是在事务中如果想要事务回滚,在使用try…catch时捕获时catch中抛出的异常必须时运行时异常,如果是不使用try…catch而是直接抛出异常的话,运行时异常和非运行时异常都会导致事务进行回滚

还有最重要的一点
注解修饰的方法被类内部方法调用
这种失效场景是我们日常开发中最常踩坑的地方;在类A里面有方法a 和方法b, 然后方法b上面用 @Transactional加了方法级别的事务,在方法a里面 调用了方法b, 方法b里面的事务不会生效。为什么会失效呢?:

其实原因很简单,Spring在扫描Bean的时候会自动为标注了@Transactional注解的类生成一个代理类(proxy),当有注解的方法被调用的时候,实际上是代理类调用的,代理类在调用之前会开启事务,执行事务的操作,但是同类中的方法互相调用,相当于this.B(),此时的B方法并非是代理类调用,而是直接通过原有的Bean直接调用,所以注解会失效。

@Service
public class ClassServiceImpl implements ClassService {

    @Autowired
    private ClassMapper classMapper;

    public void insertClass(ClassDo classDo) throws CustomException {
        insertClassByException(classDo);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void insertClassByException(ClassDo classDo) throws CustomException {
        classMapper.insertClass(classDo);
        throw new RuntimeException();
    }
}

//测试用例:
@Test
    public void insertInnerExceptionTest() throws CustomException {
       classDo.setClassId(2);
       classDo.setClassName("java_2");
       classDo.setClassNo("java_2");

       classService.insertClass(classDo);
    }

上面的这种情况是不会让事务生效的,具体原因在上卖弄查看

解决办法

public void insertClass(ClassDo classDo) throws CustomException {
//         insertClassByException(classDo);
        ((ClassServiceImpl)AopContext.currentProxy()).insertClassByException(classDo);
    }
//测试用例:
 @Test
    public void insertInnerExceptionTest() throws CustomException {
       classDo.setClassId(3);
       classDo.setClassName("java_3");
       classDo.setClassNo("java_3");

       classService.insertClass(classDo);
    }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SSM项目智慧物业平台修改5.5.zip是一个升级版的Java Web应用,它继续采用SSM(Spring Spring MVC MyBatis)框架,并结合了微信小程序前端技术。该系统为物业公司和社区居民提供更加智能化的物业管理服务,用户能够在微信环境轻松地处理物业相关事务、报修维护、参与社区活动等。 项目的主要功能可能包括: 1. **物业费用管理**:居民可以查询和缴纳物业费、停车费等,物业可以进行费用管理和账单生成。 2. **报修服务**:居民可以通过小程序提交报修请求,物业可以接收请求并安排维修。 3. **社区通知**:物业可以发布社区通知和公告,居民可以在小程序查看最新信息。 4. **访客管理**:物业可以使用小程序管理访客登记和出入记录,提高社区安全性。 5. **社区活动**:物业可以组织社区活动并通过小程序进行宣传和报名,居民可以参与活动增进邻里关系。 6. **环境监控**:集成智能硬件接口,实时监控社区环境,如公共区域的清洁度、安防监控等。 7. **居民反馈**:居民可以通过小程序提出建议或投诉,物业可以及时响应并处理反馈。 8. **智能家居控制**:对于支持智能家居的社区,居民可以通过小程序控制家的智能设备,如智能门锁、灯光等。 此外,升级版本可能增加了以下新功能: 1. **人脸识别门禁**:集成人脸识别技术,提升小区进出的便捷性和安全性。 2. **智能客服**:引入智能客服系统,提供24小时在线咨询服务,快速响应居民咨询。 3. **电子发票**:支持物业费用的电子发票功能,方便居民在线索取和打印发票。 4. **社区团购**:添加社区团购模块,方便居民在线采购生鲜、日用品等。 5. **设施预约**:允许居民通过小程序预约使用社区健身器材、会议室等公共设施。 整个项目继续采用MVC设计模式,Spring负责整体业务逻辑的处理和依赖注入,Spring MVC用于处理HTTP请求和页面跳转,而MyBatis负责与数据库的交互操作。数据库设计优化了存储结构和查询效率,以适应智慧物业平台的需求。 这个项目适合计算机科学或软件工程专业的学生作为课程设计、毕业设计或实践项目。对于希望学习SSM框架、微信小程序开发以及智能物业管理系统设计的开发者来说,这是一个实用的案例。通过参与这个项目,开发者不仅能提升Java Web开发技能,还能了解如何将现代Web技术应用于物业管理领域,提高物业服务的效率和居民的生活质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值