Spring Schedule定时关单快速入门(一)
然后领着大家来看一下,然后是Spring Schedule Cron的生成器,会教大家怎么来使用他
一句话理解,用作作业调度,如定时任务,那JDK原生的呢,提供Timer,Task,这些类来完成定时任务,那开源框架还有Quarz,
但是我们主要是使用Spring Schedule框架,那我们来看一下Spring Schedule框架的快速入门
那么Spring Schedule Cron表达式呢,其实和Quartz的表达式是一样的,我们一起来看一下,
首先秒允许的值是0到59,运行的特殊字符是逗号,横线,星号和斜杠,那分和小时允许的特殊符号一样的,
只不过小时是从0点到23点,月内日期是1到31,然后月大家看一下,1到12,或者英文,周内日期是1到7年
一般都留空,右侧的特殊符号第一次接触的时候也不用慌,我们现在来挨个解释一下,我们一起来看一下
首先是星号,代表匹配所有的值,那星号用处是最多的,第二个问号,只有在星期域和日期域中使用,他被
用来指定非明确的值,那一会在我们实际项目中,使用的Cron表达式也会用到问号,横线是指定一个范围,
如10-12,代表的是10点,11点,12点,前提是我们把10-12设置在小时域,逗号就是一个可选值,如星期一逗号,
星期三逗号,星期五逗号,斜杠是比较重要的,这里表示指定的增量,如0/15,如果在秒域意思是,每分钟的
0秒,15秒,30秒,45秒,那5/15在分钟域呢,所表示每小时的5分钟,20分钟,35分钟和50分钟,也就是说从第5分钟
开始,增量15,然后就是20,再增量15就是35,再增量15就是50,然后我们经常能看到的写法,就是*/10,其实呢,
*/10和0/10,是一样的,也就是初始值都是从0开始的,那对于星号问号,斜杠,我们实际工作当中,使用的是最多的,
下面说一下L,表示day-of-month,和day-of-week域,但是这两个字段中的意思不同,例如day-of-month呢,所表示这个
月的最后一天,那后边有一些例子,L我们实际用的不是太多,有兴趣的可以去查一下,然后我们继续来看
大家看到这么多表不要慌,一会把表达式的生成器一起来理解一下,W是只允许在日期域出现的,这个字符是指定日期的,
最近工作日,W相对复杂一些,可以仔细看一下,然后我们看一下LW,L和W是可以在日期中联合使用的,LW表示这个月最后一周的
工作日,井号是只允许在星期域中出现的,这个字符用于指定本月的某某天,而6#3表示本月第三周的星期五,那6就表示星期五,
表示第三周,毕竟Cron表达式是老外发明的,那星期日就作为一周的第一天,星期六作为一周的第七天,那第六天就是一周的
星期五,所以4#5就代表第五周的星期三,然后C是允许在星期域和日期域中出现,我们这里面就不详细的介绍了,一会我们可以做
一个实验
常用Cron表达式介绍,我们已经把年给省掉了,*/1和0/1是一样的,它是在分钟域的,后面的星是通配,
最后的问号是不确定的,所以我们只看前两个,他就代表每一分钟,请仔细看括号里面的内容,例如我从这一分钟第
30秒启动我们的项目,并不是说,他会在1分30秒的时候,两分30秒的时候,3分30秒的时候,来执行,它会在启动30秒之后,
等待30秒,等待到1分钟的整数倍的时候执行,那下面的小时也是同理,例如 0 0 */6代表每6个小时,也就是每6个小时的
整数倍,来执行,那这里我抛出一个问题,每6个小时的整数倍,那么又会在哪个时间点执行呢,然后0 0 */1这个比较简单,
每一个小时的整数倍都会执行
然后说一下Spring Schedule Cron的生成器,那这个生成器我们实际工作当中呢,使用它可以提高我们的效率,
我们在搜索引擎搜索cron生成器,现在我们演示生成器生成的方法,首先我们先搜索cron生成器,这里边有很多,
我们刚才说的 0 0 */6 * * ?,*/6和0/6是一样的,我们解析,反解析到UI,这个时候要说一下,这个网站有时候
有一些bug,这里变成了0-6
http://cron.qqe2.com/
我们再*/6反解析到UI
所以我们在使用生成器的时候要注意,如果有bug,自己去改一下,那这里面就可以看到,最近5次的
运行时间,6点,12点,18点,0点,6点,因为*/6就是0/6,0就代表从0点开始,然后没到6小时的整数倍,开始
执行,所以秒,分钟,小时的域呢,是*/6,后面的年呢,省略没有填的,这样我们就很简单的通过cron表达式,
反解析出来,他最近的一个schedule运行时间是什么样子,然后上边我们可以看一下,这里允许的通配符,
上面也是有的,然后我们可以在上面进行一个组装,组装也可以组成下面的表达式,根据实际的工作和业务
场景呢,来这里面使用cron表达式,紧接着我们要学习Spring Schedule的一个配置,首先我们要在Spring配置文件当中,
增加task,如果在IDE里边,我们可以通过快捷键,来吧xml的namespace,还有schema,自动的加上,那具体加在那个位置呢,
我们实战当中也会来讲的
继续Spring Schedule的一个配置,那么我们配置完成之后,我们要写一个Spring Schedule的类,这个类上面呢,
我们要加一个注解,
,我们通过这个注解把这个类注册为Spring容器当中的一员,然后继续,那在我们要
执行的方法上边呢,就可以加
的这么一个注解,然后我们在注解里面呢,把这个表达式写上,那这个方法我们
就可以认为是一个定时任务方法了,例如我们看一下,我们在方法上增加
,这个就代表
每一分钟执行一次
既然是关闭订单呢,我们这里就要牵扯到,MYSQL的行锁和表锁,我们会使用select * from .. for update,这种方式,
其实for update是一种悲观锁,那后续演进我们也会演进成乐观锁的,大家可以从易到难,乐观锁在表中增加一个字段,
然后它是一个version,version我们可以使用时间戳毫秒数,然后来进行一个判断,再决定这个值是否要更新,是否要回滚,
那么for update呢,是一个悲观锁,但是虽说简单,还是有很多要注意的点,我们来看一下,首先我们要使用Innodb引擎,那在
我们项目当中,都是使用的innodb引擎,然后继续看,for update在明确主键的时候,会产生行锁,如果主键不明确的话,会产生表
锁,也是一个ROW-Level Lock,一个Table-Level的Lock
例如我们mmall_product表,有id和name,id是产品的主键,name是产品的名称,首先是明确指定主键,并且有结果集的,
那就是行锁
select * from mmall_product where id = '66' for update;
我们主要看where id,id是明确的主键,并且我们产品表里有这个产品,也就代表着有结果集,那么他会产生一个行锁
明确指定主键,并且没有结果集,我们查一个id是-100的,id也是主键,但是呢没有结果集,不会上锁,也就是无lock,
select * from mmall_product where id = -100 for update;
无主键看一下
select * from mmall_product where name = 'phone' for update;
name并不是主键,所以这个SQL语句会产生锁表,会把整个表锁住,所以我们在使用for update悲观锁的时候,
这里一定是要注意的,如果一个不慎就会造成线上的故障
那主键不明确呢
select * from mmall_product where id <> 66 for update;
其实就是不等于,代表主键不明确,不等于66的主键,非常多,所以这个锁也会变成表锁,锁住整个表,
那这个是主键不明确
然后再看一下,如果用id like,那主键也是不明确,所以还会变成表锁
select * from mmall_product where id like '66' for update;
-----------------------------------------------------------------------------------------------------------------
转载出自: https://blog.csdn.net/Leon_Jinhai_Sun/article/details/94585605