第九章 spring 事务和定时任务

news/2024/7/8 0:21:04

1. spring事务

1.1 是什么?

        单个逻辑单元执行一系列的事;

        spring事务的本质就是对数据库事务的支持。

1.2 目的

        为了保证数据的完整性和一致性;事务包含一系列的动作,一旦其中有一个动作出现错误,就全部进行回滚,将已完成的操作撤销。

1.3 spring事务特性

spring事务管理策略类继承自:org.springframework.transaction.PlatformTransactionManager

这个接口;

 在TransactionDefinition接口中定义了一下特性:

        事务隔离级别;

        事务传播行为;

        事务超时;

        事务只读属性;

        spring事务回滚规则;

1.4 声明式事务管理配置的两种方式(以mybatis为例) 

1.4.1 xml配置文件的方式

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:component-scan base-package="com.service"/>

    <context:property-placeholder location="classpath:db.properties"/>
    <bean id="ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="ds"/>
        <!--mapper对应实体包位置-->
        <property name="typeAliasesPackage" value="com.entity"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--mapper xml文件-->
        <!--<property name="mapperLocations" value="classpath:com/mapper/*.xml"/>-->
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--mapper接口-->
        <property name="basePackage" value="com.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

    <!--配置声明式事务-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="ds"/>
    </bean>

    <!--配置事务增强-->
    <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
        <tx:attributes>
            <!--以insert开头的方法-->
            <tx:method name="insert*" propagation="REQUIRES_NEW" rollback-for="java.lang.ArithmeticException"/>
        </tx:attributes>
    </tx:advice>

    <!--aop 配置-->
    <aop:config proxy-target-class="true">
        <aop:pointcut id="pc" expression="execution(* com.service.impl.*.*(..))"/>
        <!--通过advisor将切面和切入点关联起来-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/>
    </aop:config>
</beans>

1.4.2 注解方式

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:component-scan base-package="com.service"/>


    <context:property-placeholder location="classpath:db.properties"/>
    <bean id="ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="ds"/>
        <!--mapper对应实体包位置-->
        <property name="typeAliasesPackage" value="com.entity"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--mapper xml文件-->
        <!--<property name="mapperLocations" value="classpath:com/mapper/*.xml"/>-->
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--mapper接口-->
        <property name="basePackage" value="com.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

    <!--配置声明式事务-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="ds"/>
    </bean>
    
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
</beans>

在事务管理的类或者方法上添加注解 @Transactional

@Service
public class RoleServiceImpl implements IRoleService {
    @Resource
    private RoleMapper roleMapper;

    @Resource
    private IDeptService deptService;
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public int insertRole(Role role) {
        Integer count = roleMapper.insertRole(role);
        deptService.insertDept(new Dept("d5"));
        return count;
    }
}

在类上使用时,类中所有的public方法都将使用事务;若类中某个方法不想使用事务,则可以使用:@Transactional(propagation = Propagation.NOT_SUPPORTED)

1.5 事务的传播性

① @Transactional(propagation=Propagation.REQUIRED):默认级别;特点:上下文中存在事务,就加入该事务中执行,不存在事务就新建事务执行;

② @Transactional(propagation=PROPAGATION.SUPPORTS):支持;特点:上下文中有事务就加入事务中执行,没有事务就用非事务的方式;

③  @Transactional(propagation=PROPAGATION.MANDATORY):强制;特点:上下文必须存在事务,否则抛出异常;

④  @Transactional(propagation=PROPAGATION.REQUIRES_NEW):要求新的;特点:每次都要新建一个事务,同时将上下文中的事务挂起,当新建事务执行完成后,再恢复执行;

⑤  @Transactional(propagation=PROPAGATION.NOT_SUPPORTED) :不支持;特点:上下文中存在事务则挂起事务,执行当前逻辑,结束后恢复上下文事务;

⑥  @Transactional(propagation=PROPAGATION.NEVER):无事务;特点:要求上下文中不能存在事务,有事务则抛出runtime异常,强制停止执行;

⑦  @Transactional(propagation=PROPAGATION.NESTED):嵌套级别;特点:上下文中存在事务则嵌套事务执行,不存在事务则新建事务。

 1.6 事务的隔离级别

用于多事务并发执行时;

①   @Transactional(isolation = Isolation.SERIALIZABLE):事务串行执行;

②   @Transactional(isolation = Isolation.REPEATABLE_READ):保证事务不会修改由另一个事务读取但是未提交(回滚)的数据;

③   @Transactional(isolation = Isolation.READ_COMMITTED):大多主流数据库的默认事务级别,保证了一个事务不会读到另一个并行事务已经修改但未提交的数据;

④   @Transactional(isolation = Isolation.READ_UNCOMMITTED):保证读取过程中不会读取到非法数据。

 2. 定时任务

spring相关的包+

        <!--定时任务需要的包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.3.10</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.2</version>
        </dependency>

2.1 配置文件方式

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">

    <context:component-scan base-package="com.service,com.advise,com.util"/>

    <task:scheduled-tasks>
        <task:scheduled ref="myTask" method="job1" cron="* * * * * *"/>
    </task:scheduled-tasks>
</beans>
@Component("myTask")
public class TaskJob {

    public void job1(){
        System.out.println("rr!"+ LocalDateTime.now());
    }

    public void job2(){
        System.out.println("ww!"+LocalDateTime.now());
    }
}

2.2 使用注解方式

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">

    <context:component-scan base-package="com.service,com.advise,com.util"/>
    <context:annotation-config/>
    <!--开启这个配置spring才能识别@Scheduled注解-->
    <task:annotation-driven />
</beans>
public class TaskJob {
    @Scheduled(cron = "3 1 * * * *")
    public void job1(){
        System.out.println("rr!"+ LocalDateTime.now());
    }

    @Scheduled(cron = "*/5 * * * * *")
    public void job2(){
        System.out.println("ww!"+LocalDateTime.now());
    }
}

2.3 cron表达式

字段(按顺序,共6个)允许值允许的特殊字符
0-59, - * /
0-59, - * /
小时0-23, - * /
日期1-31, - * / ?  L  W  C
月份1-12 或 JAN-DEC, - * /
星期1-7 或 SUN-SAT, - * / ? L C #
年(可选)留空  或  1970-2099, - * /

特殊字符:

, 列出枚举值

- 区间

* 通配

/  起始时触发后,隔固定时间触发一次

L 最后

W 有效工作日(周一到周五)

LW 连用  每月最后一个星期五

# 确定每个月的第几个星期几


http://lihuaxi.xjx100.cn/news/7612.html

相关文章

新零售数智化转型,需要怎样的数据底座?

行业发生变革前&#xff0c;转型是通过信息化发生的&#xff0c;但信息化只是将业务流程从线下搬到了线上&#xff0c;以计算机网络为载体支撑商业活动&#xff0c;数据本身其实并没有被分析、被应用&#xff0c;发挥核心价值。随着新兴技术的高速发展&#xff0c;新零售转型正…

什么情况会导致@Transactional事务失效?

一个程序中不可能没有事务&#xff0c;而 Spring 中&#xff0c;事务的实现方式分为两种&#xff1a;编程式事务和声明式事务&#xff0c;又因为编程式事务实现相对麻烦&#xff0c;而声明式事务实现极其简单&#xff0c;所以在日常项目中&#xff0c;我们都会使用声明式事务 T…

基于C++QT5的学生信息综合管理系统

摘 要 在信息技术不断推陈出新的背景下, 针对传统人工管理学生信息方式效率低, 提出一种基于 C 语言的学生信息管理系统。 本设计主要通过使用 C 程序设计语言&#xff0c;按照大作业的相关要求在实现增删改查功能时&#xff0c;数据结构均采用链表实现&#xff0c;同时程序均采…

帅呆了!Kafka移除了Zookeeper!

普天同庆!最新版的Kafka 2.8.0&#xff0c;移除了对Zookeeper的依赖&#xff0c;通过KRaft进行自己的集群管理。很好很好&#xff0c;终于有点质的改变了。 一听到KRaft&#xff0c;我们就想到了Raft协议。Raft协议是当今最流行的分布式协调算法&#xff0c;Etcd、Consul等系统…

JS 对象之扩展、密封和冻结

有时候我们写了一个js库&#xff0c;里面有一些核心对象&#xff0c;我们希望在开发过程中这个核心对象不被修改&#xff0c;这时候就要防止该对象被篡改&#xff0c;以达到保护对象属性的目的&#xff0c;可通过以下三个方法去实现 一、扩展 语法&#xff1a;Object.prevent…

Liunx 部署后端服务jar包脚本

1.停止指定端口进程&#xff0c;部署服务 #!/bin/bash # jar包名称 app_namedigital-service-1.0-SNAPSHOT.jar # 服务器jar包路径 app_path/home/jar/ # 指定端口 app_port9199 # 杀掉指定端口的应用进程 pidnetstat -apn|grep $app_port|awk {print $7}|cut -d/ -f1 echo &qu…

软件测试的学习笔记(1)

一、认识 1.什么是软件测试&#xff1f; 软件测试就是软件测试人员验证软件是否满足用户的需求。 2.软件测试和软件开发的区别&#xff1f; &#xff08;1&#xff09;本身 开发&#xff1a;广度小&#xff0c;专业度高 测试&#xff1a;所需要技能比较…

MySQL数据库之用户管理

一、mysql中常见的的约束/规则 ① 主键约束&#xff08;primary key&#xff09; ② 外键约束&#xff08;foreign key&#xff09;&#xff1a; 如果同一个属性字段在表一中为主键&#xff0c;而在表二中不是主键&#xff0c;则字段称为表二的外键。 ③ 非空约束&#xff08;…