第九章 spring 事务和定时任务

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 连用  每月最后一个星期五

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值