spring的Task定时任务与事务

Posted 韶光不负

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring的Task定时任务与事务相关的知识,希望对你有一定的参考价值。

目录

SpringTask定时任务

xml方式

1,加载Sring核心依赖(pom.xml配置)

2,添加配置文件,添加IOC扫描器

3,定义定时任务

4,加载定时器下xml配置

6,现象证明

注解方式

定时方法

xml配置

现象

Cron表达式

Spring事务

事务的四大特性(ACID)

原子性(Atomicity)

隔离性(lsolation  四个隔离级别)

持久性(Durability)

Spring的事务

Spring事务的实现

xml方式

注解配置


SpringTask定时任务

在项目中开发定时任务应该一种比较常见的需求,在Java中开发定时任务主要有三种解决方案:一是使用JDK自带的Timer,二是使用第三方组件Quartz,三是使用Spring Task


Timer是JDK自带的定时任务工具,其简单易用,但是对于复杂的定时规则无法满足,在实际项目开发中也很少使用到。

Quartz功能强大,但是使用起来相对笨重。

Spring Task则具备前两者的优点(功能强大且简单易用),使用起来很简单,除Spring相关的包外不需要额外的包,而且支持注解和配置文件两种形式。
 

xml方式

1,加载Sring核心依赖(pom.xml配置)

 <!-- 添加spring核心依赖       -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.16.RELEASE</version>
        </dependency>

2,添加配置文件,添加IOC扫描器

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">


        <!--
            使用注解方式进行创建对象
            1.开启注解扫描
            含义:开启注解扫描,指定了 base-package 扫描指定的包,扫描包与子包中所有的类
            查看类上是否有指定的注解, 如果类上有指定的注解,那么就创建给类对象,
            放到spring容器中
        -->
        <context:component-scan base-package="com.lsf"/>
        
</beans>

3,定义定时任务

package com.lsf.job;

import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

@Component //交给Ioc维护
public class Taskjob 

    //定义定时任务
    public void job()
        System.out.println("任务"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    

4,加载定时器下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: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
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task.xsd">


        <!--
            使用注解方式进行创建对象
            1.开启注解扫描
            含义:开启注解扫描,指定了 base-package 扫描指定的包,扫描包与子包中所有的类
            查看类上是否有指定的注解, 如果类上有指定的注解,那么就创建给类对象,
            放到spring容器中
        -->
        <context:component-scan base-package="com.lsf.job"/>


        <!-- 定义定时规则       -->
        <task:scheduled-tasks>
                <!-- 定义规则二秒一次    cron="0/2 * * * * ? 0/2              -->
                <task:scheduled ref="taskjob" method="job" cron="0/2 * * * * ?"/>
        </task:scheduled-tasks>
</beans>

6,现象证明

package com.lsf;


import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Starter 

    public static void main(String[] args) 
        BeanFactory factory = new ClassPathXmlApplicationContext("spring.xml");
    

注解方式

前面配置相同,区别说方法与xml配置

定时方法

package com.lsf.job;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

@Component //交给Ioc维护
public class Taskjob 

    //定义定时任务  Scheduled 定时任务注解
    @Scheduled(cron="0/2 * * * * ?")
    public void job()
        System.out.println("任务"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    

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: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
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task.xsd">


        <!--
            使用注解方式进行创建对象
            1.开启注解扫描
            含义:开启注解扫描,指定了 base-package 扫描指定的包,扫描包与子包中所有的类
            查看类上是否有指定的注解, 如果类上有指定的注解,那么就创建给类对象,
            放到spring容器中
        -->
        <context:component-scan base-package="com.lsf.job"/>


        <!-- 开启定时任务驱动       -->
        <task:annotation-driven></task:annotation-driven>
</beans>

现象

Cron表达式

关于cronExpression表达式有至少6个(也可能是7个)由空格分隔的时间元素。从左至右,这些元素的定义如下(,表示间隔):

  1. 秒(0-59)
  2. 分钟(0-59)
  3. 小时(0-59)
  4. 月份中的日期(1-31)
  5. 月份(1-12或,JAN-DEC)
  6. 星期中的日期(1-7或 SUN-SAT)
  7. 年份(1970-2099)

例如:
0  0  18 , 14, 16   *   *  ?
每天上午10点,下午2点和下午4点


0  0,15,30,45  *  1-10  *  ?
每月前1日天每隔15分钟


30 0 0 1 1 ? 2012
在2012年1月1日午夜过30秒时
 

Spring事务

事务的四大特性(ACID)

Spring并不直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。
 

原子性(Atomicity)


共生死,要么全部成功,要么全部失败!。一致性(Consistency)
事务在执行前后,数据库中数据要保持一致性状态。(如转账的过程账户操作后数据必须保持一致)·

隔离性(lsolation  四个隔离级别)

事务与事务之间的执行应当是相互隔离互不影响的。(多个角色对统一记录进行操作必须保证没有任何干扰),当然没有影响是不可能的,为了让影响级别降到最低,通过隔离级别加以限制:

1.READ_UNCOMMITTED(读未提交)
隔离级别最低的一种事务级别。在这种隔离级别下,会引发脏读、不可重复读和幻读。

2.READ_COMMITTED(读已提交)
读到的都是别人提交后的值。这种隔离级别下,会引发不可重复读和幻读,但避免了脏读。

3.REPEATABLE_READ(可重复读)
这种隔离级别下,会引发幻读,但避免了脏读、不可重复读。

4.SERIALIZABLE(串行化)
最严格的隔离级别。在Serializable隔离级别下,所有事务按照次序依次执行。脏读、不可重复读、幻读都不会出现。

持久性(Durability)

提交完事务后,数据库中数据改变是永久的
 

Spring的事务

Spring事务管理器的接口是org.springframework.transaction.PlatformTransactionManager,通过这个接口,Spring 为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了

public interface PlatformTransactionManager()
    //由TransactionDefinition得到TransactionStatus对象
    TransactionStatus getTransaction(TransactionDefinition definition) throwsTransactionException ;
    //提交
    void commit(TransactionStatus status) throws TransactionException;
    //回滚
    void rollback (TransactionStatus status) throws TransactionException;

具体的事务管理机制对spring 来说是透明的,它并不关心那些,那些是对应各个平台需要关心的,所以Spring事务管理的一个优点就是为不同的事务API提供一致的编程模型,如 JTA、JDBC、Hibernate,JPA

Spring事务的实现

xml方式

        1,xml添加事务命名方式与aop名命方式

        事务

     xmlns:tx="http://www.springframework.org/schema/tx"
 
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx.xsd

        apo

     xmlns:tx="http://www.springframework.org/schema/aop"
 
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/tx/spring-aop.xsd

        2,开启aop自动代理

<!--开启AOP代理-->
<aop :aspectj-autoproxy / >

        3,配置事务管理器

<--事务管理器定义-->
<bean id="txManager" class="org.springframework . jdbc.datasource .DataSourceTransactionManager">
    <!--数据源-->
    <property name="dataSource" ref="dataSource"></property>
< / bean>

        4,配置事务通知

<tx :advice id="txAdvice" transaction-manager="txManager ">
    <!--对以add update delete query开头的所有方法进行事务处理-->
    <tx :attributes>
        <!--定义什么方法需要使用事务name代表的是方法名(或方法匹配)--><! --匹配以add开头的所有方法均加入事务-->
        <tx :method name="add*" propagation="REQUIRED”/>
        <! --匹配以update开头的所有方法均加入事务
        <tx :method name= " update*" propagation=" R4U RED"/>
        <!--匹配以delete开头的所有方法均加入事务
        <tx:method name="delete*" propagation="REQUIRED"/>
        <! --匹配以query开头的方法设置只读状态-->
        <tx :method name= " query*" read-only="true" />
    </tx :attributes>
</tx :advice>

        5,配置aop

        

<!-- aop切面定义(切入点和通知)-->
<aop:config>
    <!--设置切入点设置需要被拦截的方法-->
    <aop : pointcut expressionm"execution(* com.xxxx.service ..* . *( . .) )" id="cut" />                                        <!--设置通知事务通知-->
    <aop :advisor advice-ref="txAdvice" pointcut-ref="cut"" />
<aop : adviso

注解配置

        1,配置事务管理器

<!-- spring注解式事务声明-->
< !--事务管理器定义-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
< / bean>

        2,支持注解

<tx : annotation-driven transaction-manager="txManager " />

        3,方法上加入事务注解

@override
@Transactional(propagation=Propagation . REQUIRED)
public void saveUser (String userName , String userPwd )
    User user1=new User( );
    user1.setUserName (userName ) ;
    user1.setUserPwd (userPwd ) ;
    userDao .saveUser(user1);userDao.delUserById(2);

备注:默认spring事务只在发生未被捕获的runtimeexcetpion时才回滚。
 

以上是关于spring的Task定时任务与事务的主要内容,如果未能解决你的问题,请参考以下文章

spring的Task定时任务与事务

Spring Task 定时任务

Spring task定时任务

spring task 定时

Spring Task定时任务

Spring Task定时任务