spring的Task定时任务与事务
Posted 韶光不负
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring的Task定时任务与事务相关的知识,希望对你有一定的参考价值。
目录
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个)由空格分隔的时间元素。从左至右,这些元素的定义如下(,表示间隔):
- 秒(0-59)
- 分钟(0-59)
- 小时(0-59)
- 月份中的日期(1-31)
- 月份(1-12或,JAN-DEC)
- 星期中的日期(1-7或 SUN-SAT)
- 年份(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定时任务与事务的主要内容,如果未能解决你的问题,请参考以下文章