博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ejb3中的@Schedule中的persistent属性的深入探索
阅读量:7067 次
发布时间:2019-06-28

本文共 3024 字,大约阅读时间需要 10 分钟。

标题:ejb3中的@Schedule中的persistent属性的深入探索

1 实验环境:

    应用服务器:glassfish4.0

    数据库服务器: MYSQL Target Server Version : 50614

    开发工具: netbeans8.0

2 我思考的问题:当我开发好了一个@Schedule定时任务之后,我开始思考这样一种场景,如果我的应用服务器(glassfish4)是集群,那么我的定时任务会怎么执行,因为在你发布一个项目到glassfish集群中,每一台jvm中都会运行相同的程序。那定时器也必然存在多份。那么我的定时器组件会在同一时间点执行多次吗(执行在多个jvm中)?

如果不会,是什么机制控制定时器的统一性,如果会,那么我们又改怎么解决呢?

3 在编写一个定时器任务时,代码如下:

@Schedule(second = "*/5", minute = "*", hour = "*", persistent = true,info = "我是定时器")    public void doWork() {	System.out.println("timer: " + System.currentTimeMillis()); }
(1 ) persistent  值官方给出的说明是 Specifies whether the timer that is created is persistent.指定在创建该定时器是否需要持久化.

(2 )时间格式的参数你可以参考的别的文章,我本文中主要介绍persistent这个值的情况,该值的默认值是true,也就说定时器的数据信息室会保存到数据库去的,那么他保存到那个数据去了呢? 其实如果你设置了persistent等于true或者不设置,定时器的数据信息都会保存到内存数据库中。

对应的物理路径如下:D:\AppServer\my-glassfish4\glassfish\domains\domain1\lib\databases 你可以尝试删除该文件夹的内容试一试,看看变动后的效果。

4 那么既然是可以保存到数据库,那么是否也可以保存到mysql数据库呢。而不是内存数据库呢,答案是可以的。

 在mysql中配置GlassFish中使用EJBTimer,需要有一个独立的数据源,和数据表EJB__TIMER__TBL,建表语句可在[glassfish安装目录]\glassfish\lib\install\databases中找到。对于developer模式,GlassFish默认使用内置的__TimerPool,不需要你手工创建datasource和表;对于cluster模式,Admin Server会默认使用__TimerPool,Cluster则需要单独配置。如果让Admin Server和Cluster同时使用手工创建的datasource,则可能导致Cluster配置中的timer datasource在server重启后丢失,TimerService会出现异常,这应该是GlassFish的BUG,目前的解决方案就是Admin Server用默认的Timer配置,Cluster用另外的配置。

建表语句如下:

CREATE TABLE EJB__TIMER__TBL (    `CREATIONTIMERAW`      BIGINT        NOT NULL,    `BLOB`                 BLOB,    `TIMERID`              VARCHAR(255)  NOT NULL,    `CONTAINERID`          BIGINT        NOT NULL,    `OWNERID`              VARCHAR(255)  NULL,    `STATE`                INTEGER       NOT NULL,    `PKHASHCODE`           INTEGER       NOT NULL,    `INTERVALDURATION`     BIGINT        NOT NULL,    `INITIALEXPIRATIONRAW` BIGINT        NOT NULL,    `LASTEXPIRATIONRAW`    BIGINT        NOT NULL,    `SCHEDULE`             VARCHAR(255)  NULL,    `APPLICATIONID`        BIGINT        NOT NULL,    CONSTRAINT `PK_EJB__TIMER__TBL` PRIMARY KEY (`TIMERID`) );

把该ejbtimer_mysql.sql放到数据中执行,然后配置一个数据库连接池,我这里就直接修改默认的数据连接池__TimerPool。

建表语句是在test库中执行的,这样配置之后你的ejb定时器使用的就是你自定义的数据库了。然后重新启动glassfish服务器,并把你定时器任务程序发布到glassfish上去。若果发布中提示EJB__TIMER__TBL表找不到,那你应该是忘记执行建表sql了。好了当我定时应用程序启动后:

这是我的代码程序:

/** * 测试定时器的持久化状态 * @author 845885222@qq.com */@Singletonpublic class NewSessionBean {    @Schedule(second = "*/5", minute = "*", hour = "*", persistent = true, info = "我是定时器")    public void doWork() {	System.out.println("timer: " + System.currentTimeMillis());    }    @Schedule(second = "*/6", minute = "*", hour = "*", persistent = true, info = "doWork2")    public void doWork2() {	System.out.println("doWork2: " + System.currentTimeMillis());    }}
控制台输出结果如下:

信息:   Redirecting to /common/index.jsf信息:   Admin Console: Initializing Session Attributes...信息:   timer: 1433846450001信息:   doWork2: 1433846454001

观察我mysql数据test下的EJB__TIMER__TBL,结果如下

以后集群就不在担心定时器不同步的问题了。

你可能感兴趣的文章
python中的数据类型(list,tuple,dict,set,None)
查看>>
通过 Snabbdom 理解 Virtual DOM
查看>>
原生JS实现类似《掘金》网站的图片查看器
查看>>
微服务架构下,解决数据一致性问题的实践
查看>>
2019,Web前端开发还值得学吗?
查看>>
理财基金篇二——基金理财的种类
查看>>
HTTP协议(2)
查看>>
2018.12.19|区块链技术头条
查看>>
React知识点:关于className处理
查看>>
CSS 中的 Grid 布局 完全指南
查看>>
简介响应状态码1xx、2xx、5xx
查看>>
线程死锁
查看>>
超级易懂的互联网通信(上)
查看>>
Java如何创建临时文件并打印File各种属性
查看>>
说说如何利用 Oracle 命令来解决函数运行错误
查看>>
使用docker-compose搭建zabbix
查看>>
亚马逊频频失约 遭消费者起诉
查看>>
vim set ts=4 自动缩进
查看>>
交互体验设计优秀的产品
查看>>
A记录(主机名解析)、CNAME(别名解析)和URL转发(域名转发)
查看>>