SpringBoot工程中的事务控制实践和三大JAVAEE组件注册及应用

SpringBoot工程中事务控制

概述

Spring 框架中提供了一种声明式事务的处理方式,此方式基于AOP代理,可以将具体业务逻辑与事务处理进行解耦。也就是让我们的业务代码逻辑不受污染或少量污染,就可以实现事务控制。

事务控制

SpringBoot工程中,可以通过@Transactional注解描述业务类或方法,进而告诉Spring框架,类中的所有方法或某些方法为切入点方法。这些方法执行时会进行事务控制。例如:

@Transactional(readOnly = false,rollbackFor = Throwable.class)
public class XxxServiceImpl implements XxxService{
  @Transactional(readOnly=true) //方法上的事务控制策略优先级高
  int deleteById(Long... id)
}

其中,@Transactional常用属性有:

timeout:事务的超时时间,默认值为-1,表示没有超时显示。如果配置了具体时间,则 超过该时间限制但事务还没有完成,则自动回滚事务。这个时间的记录方式是在事务 开启以后到 sql 语句执行之前。
read-only:指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的 方法,比如读取数据,可以设置 read-only 为 true。对添加,修改,删除业务 readonly 的值应该为 false。
rollback-for:用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指 定,各类型之间可以通过逗号分隔。
no-rollback- for: 抛出 no-rollback-for 指定的异常类型,不回滚事务。
isolation 事务的隔离级别,默认值采用 DEFAULT。当多个事务并发执行时,可能会 出现脏读,不可重复读,幻读等现象时,但假如不希望出现这些现象可考虑修改事务 的隔离级别(但隔离级别越高并发就会越小,性能就会越差)

事务控制原理

Spring 事务管理是基于接口代理(JDK)或动态字节码(CGLIB)技术,然后通过 AOP 实 施事务增强的。当我们执行添加了事务特性的目标方式时,系统会通过目标对象的代理对 象调用 DataSourceTransactionManager 对象,在事务开始的时,执行 doBegin 方法, 事务结束时执行 doCommit 或 doRollback 方法。如图所示:
请添加图片描述
SpringBoot工程中的事务控制方式应用相对比较简单,但底层实现原理相对比较复杂,先应用,后续逐步分析其实现原理即可。

监听器(Listener)

定义监听器

package com.jt.listener;
import org.springframework.stereotype.Component;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
 * 这里的监听器用于监听服务的启动和销毁
 */

public class DemoListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("服务启动了");
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("服务销毁了");
    }
}

注册监听器

package com.jt.config;
/**
 * 在这里配置javaee规范中的三大组件
 */
@Configuration
public class ComponentConfig {
    ......
    //注册监听器
    @Bean
    public ServletListenerRegistrationBean servletListenerRegistrationBean(){
        ServletListenerRegistrationBean bean=
                new ServletListenerRegistrationBean(new DemoListener());
        return bean;
    }
}

启动服务测试

启动服务,检测服务日志输出,监听器方法是否执行

过滤器(Filter)

定义过滤器

package com.jt.filter;
import javax.servlet.*;
import java.io.IOException;
/**
 * javaee规范中的过滤器,对请求和响应数据进行过滤
 * 1)统一数据的编码
 * 2)统一数据格式校验 (今日头条的灵犬系统)
 * 3)统一身份认证
 */
public class DemoFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        System.out.println("==doFilter==");
        servletRequest.setCharacterEncoding("UTF-8");
        String id= servletRequest.getParameter("id");
        System.out.println("id="+id);
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

注册过滤器

package com.jt.config;

/**
 * 在这里配置javaee规范中的三大组件
 */
@Configuration
public class ComponentConfig {

    ....
    //注册过滤器
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean bean=
                new FilterRegistrationBean(new DemoFilter());
        bean.addUrlPatterns("/hello");//对哪个请求进行处理
        return bean;
    }

}

访问过滤器

启动服务,对于以/hello开头的url进行访问,检测日志输出

处理器(Servlet)

定义处理器

package com.jt.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * JavaEE规范中的Servlet
 */
public class DemoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("==doGet==");
        resp.getWriter().println("hello client");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
    //...
}

注册处理器

package com.jt.config;

/**
 * 在这里配置javaee规范中的三大组件
 */
@Configuration
public class ComponentConfig {
    .....
    //注册servlet
    @Bean
    public ServletRegistrationBean servletRegistrationBean(){
        ServletRegistrationBean bean=new ServletRegistrationBean();
        bean.setServlet(new DemoServlet());
        bean.addUrlMappings("/hello");
        return bean;
    }
}

访问处理器

启动服务,对于以/hello开头的url进行访问,检测日志输出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值