Tomcat 7.0.23 & Spring 3.1 & task scheduler multiple invocations - spring

my spring.xml looks like
<task:scheduler id="feedServiceScheduler" pool-size="10"/>
<task:scheduled-tasks scheduler="feedServiceScheduler">
<task:scheduled ref="feedService" method="testMethod" cron="0 50 11 * * *" />
</task:scheduled-tasks>
I expect method "testMethod" to be invoked on object "feedService" at 11:50 every day of the year
For some reason testMethod is invoked twice and I just can't find a solution to the problem.
"feedService" bean is nothing fancy, just a simple POJO and test method prints out a message.
Any help about what I might be doing wrong would be great.
Thanks

Same problem here. As it seems, tomcat creates multiple servlet instances, so scheduled procs are scheduled multiple times so.
Here is a little log, where you can see the runs initiated on different classes:
[2012-03-22 11:03:00,001] [ClickCheatReportGenerator] DEBUG ClickCheatersender called (com.innofeed.mindenkupon.schedules.ClickCheatReportGenerator#5238d01c)
[2012-03-22 11:03:00,004] [ClickCheatReportGenerator] DEBUG ClickCheatersender called (com.innofeed.mindenkupon.schedules.ClickCheatReportGenerator#fe70870)
[2012-03-22 11:03:00,004] [ClickCheatReportGenerator] DEBUG ClickCheatersender called (com.innofeed.mindenkupon.schedules.ClickCheatReportGenerator#8daf938)
You should limit tomcat to run only 1 servlet instance, but maybe that will cause performance issues.
Update:
Finally solved the problem using cron schedules calling for urls handled by controllers.

Related

Spring #Scheduled, how to run once at time (not concurrently)

I have an annotated method width #Scheduled with an cron of */15 * * * * ? (run each 15 seconds).
Sometimes this process take more than 15 seconds to run.
Is there any way to avoid the call of the #Scheduled if it's already running?
My workaround currently is a flag field in the class to signal if the process is running, and if it is marked the code exits before execute the main code.
I think it's already the case, if the first job has'nt finished, the second will not start.
See :
How to prevent overlapping schedules in Spring?
If it isn't working, you can also use an AtomicBoolean to check if you must start the process or not.

How to override Transaction service timeout value in WAS Console by code?

In my xml file, I have something as follow:
<bean id="transactionManager"
class="org.springframework.transaction.jta.WebSphereUowTransactionManager"
p:defaultTimeout="60" />
<bean id="sharedTransactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<constructor-arg>
<ref bean="transactionManager" />
</constructor-arg>
<property name="isolationLevelName" value="${sharedTransactionTemplate.isolationlevel:ISOLATION_READ_UNCOMMITTED}"/>
<property name="timeout" value="60"/>
</bean>
With the value 60, my program will hit timeout if the response from db taking more than 60 seconds. This is correct and also what I expected.
And I found that there is some transaction time out value setting in WAS Console as well:
Server --> WebSphere application servers --> my server
Under Container Settings --> click on Container Services --> Transaction service
Inside Transaction service page, there is a value call "Total transaction lifetime timeout ". I set the value to 80.
In my application, I have a part that will trigger Spring SimpleJobLauncher to run a spring batch in my application. In my Spring batch, I have some for loop which is write some data in log file, and it does not have any interaction with DB.
I found that, my for loop will not hit the 60 seconds time out after 60 seconds. It will only hit the 80 seconds time out. I believe that it is because of it didn't call db.
My code is something as follow:
#Autowired
#Qualifier("sharedTransactionTemplate")
private TransactionTemplate transactionTemplate;
transactionTemplate.execute( new TransactionCallbackWithoutResult( ) {
// In here I trigger the spring batch
} );
I would like to edit this value to for example 70 seconds base on code in xml or any way. I do not want to edit it in WAS Console because I still want other method still using the 80 seconds.
Any ideas?
Here is what my spring batch doing:
Call db, update something. (done with no error)
reader, read data from db. (done with no error)
Before write, i got some for loop which is not call db. --> hit timeout here, I found that the timeout value is the value that set in WAS Console, instead of the value set in xml.
and so on...
I actually want to do something that I can code in xml, so that this spring batch can use my own value set in xml. SO that my step 3 can use my own value.
Additional question, are these following class only applicable for transaction that involve connection to database?
class="org.springframework.transaction.jta.WebSphereUowTransactionManager"
class="org.springframework.transaction.support.TransactionTemplate"
It is unclear to me from the info you've provided why you are executing your Spring Batch job transactionally, you may want to consider whether you need to. Although not a duplicate, this question is similar to this one in which you can see one possible solution is to start a UserTransaction for your spring batch job which you can control the timeout. As pointed out in that answer and subsequent comments, there are some limitations and considerations about using this method.

Spring scheduled work at 21:30 gmt+3

I'm trying to trigger a method with spring #Scheduled . I thought i should use zone but nothing happens. By the way I'm increasing minute like 30,31,32 for test also tried for gmt+2 and gmt+3.
This is the annotation i try-->
#Scheduled(cron = "0 30 21 * * * " , zone="Europe/Moscow")
Anyone know why ? Where did i go wrong ? Thanks in advance
You have set when the scheduler is to run, but possibly not actually enabled it.
Add #EnableScheduling to where you have defined your main Application class.

Drools loading session seems to fire rules

I am at a loss with this and can't seem to find an answer in the docs. I am observing the following behaviour. I have this rule:
import function util.CSVParser.parse;
declare Passenger
#role(event)
#expires(24h)
end
rule "Parse and Insert CSV"
when
CSVReadyEvent( $csv_location : reader ) from entry-point "CSVReadyEntryPoint";
$p : Passenger() from parse($csv_location);
then
insert( $p );
end
I can then enter my CSVReadyEvent into my session and call fireAllRules and it executes correctly. It hits the safe point at the end, and all is cool.
I then restart my app and load the session like this:
KieSession loadedKieSession = kieServices.getKieService().getStoreServices().loadKieSession(session.getId(), kieBase, ksConf, kieServices.getEnvironment());
The base and config I take from my kmodule.xml.
What happens now is that WITHOUT calling fireAllRules() loading the session somehow triggers fireing all rules.
I do not understand how unmarshalling triggers rule execution but this is obviously wrong. I have already executed that rule, and it should not be executed twice.
In a test case (my tests do NOT create persistent sessions because I only want the rules to be tested) I can call fireAllRules() twice, and the second time does not trigger any matched rules. I am not exactly sure what goes wrong, but the persistent session seems to be loaded in an odd way. Or the persisting of the session is wonky and forgets that it had executed the rule already.
Does anyone have inside in this? I am more than happy to share any code.
Here's my persistence.xml:
<persistence-unit name="org.jbpm.persistence.jpa" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.drools.persistence.info.SessionInfo</class>
<class>org.drools.persistence.info.WorkItemInfo</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.max_fetch_depth" value="30" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform" />
</properties>
</persistence-unit>
Thanks!
An update/answer from a painful painful painful day of debugging and testing and running stuff:
I suspected my hibernate setup was wrong, so the wrong thing got persisted. I ended up throwing that approach away and writing a manual marshalling/de-marshalling thing.
After creating/loading/recreating/loading I can confirm the session NEVER changes on file.
This was interesting to me because I could swear that the rules are executed, and I was half right:
The WHEN part is executed when the session is loaded. Why? I have not the slightest idea...
I was chasing a red hearing because I am calling a function in my when part (as you can see in the rule) to iterate and insert all facts based on that event I am receiving.
My parse function obviously has logging, so each time I reload the session, I get a storm of log flying through my terminal hinting that my rules are being executed.
I then changed my rules to be very very specific (as in output everywhere I possible can). I debugged as deep as I could and I still can't seem to be able to pinpoint as to why on earth recreating the session is executing the when part of a rule. I settled on this: Magic. And with a little more detail:
The documentation of drools persistence https://docs.jboss.org/jbpm/v6.2/userguide/jBPMPersistence.html states that the guys implemented their own serialze/deserialize strategy in order to speed up the process. I resolve to blame this custom strategy on what I am seeing.
Lesson learned:
Do NOT create objects in the when part (because this will slow you down when loading a session since all when parts are executed)
Chasing red herrings is a pain in my butt.
So to sum up: I believe (up to say 99%) that loading a session is NOT executing the rules.
Using events in real mode and in a STREAM session running due to fireUntilHalt on the one hand and saving and restarting sessions with fireAllRules are somewhat contradictory paradigms.
If you have events, I suggest that you use the API to set up and start a (stateful) session in a thread, and insert facts (events) as they arrive.

Spring task scheduler first task execution time

After some research on spring task scheduler and task executor, I found below spring config would run myTask.run method every second.
<bean id="myTask" class="com.amazon.path.to.MyTask"/>
<task:scheduled-tasks scheduler="myScheduler">
<!--run once every second-->
<task:scheduled ref="myTask" method="run" fixed-rate="1000"/>
<!--alternatively, run constantly, waiting one second after each run finished to start the next-->
<!--<task:scheduled ref="myTask" method="run" fixed-delay="1000"/>-->
</task:scheduled-tasks>
<task:scheduler id="myScheduler" pool-size="1"/>
I want to know exactly when first invocation of the myTask.run occurs. It is mentioned nowhere in the docs. I referred Spring XSD for this. Also element "task:scheduler" creates instance of ThreadPoolTaskScheduler which from Spring Doc has method
scheduleAtFixedRate(Runnable task, Date startTime, long period)
which has startTime parameter. But in XSD reference above, there is no such attribute.

Resources