Transaction synchronization between threads

classic Classic list List threaded Threaded
28 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Transaction synchronization between threads

Cheng Fang
A jberet user reported JBERET-29 (Foreign key constraint step_execution_jobexecutionid_fkey fails when using Postgresql on WildFly, and we are trying to fix it by jberet 1.0.0.Final.  The problem happens when user app starts a job within a transaction (e.g., CMT EJB), jberet inserts JobExecution into database (thread 1 & transaction 1), and then spawn a jberet-batch thread to run the job (thead 2 & transaction 2).  Sometimes T2 tries to access db before T1 is committed, hence the error reported by the user.

What's the common approach for solving this kind of problem?  I suppose other WildFly components may also have this issue and probably already solved.  Using transaction synchronization is a cleaner solution than polling db, but I'm not sure about its full implication.  Ideally, I don't want to use system level JTA API like TransactionManager or Synchronization in jberet proper, but probably we can implement it in WildFly jberet integration.

Thanks,
Cheng

_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

Stuart Douglas
I would use a transaction synchronization, so you don't spawn the other thread until the transaction is successfully committed.

What does the spec say about transactions? If a job is create in a thread that is part of a transaction and the transaction is rolled back should the job actually go ahead? Common sense would suggest not.

Stuart



On Tue, Feb 4, 2014 at 4:49 PM, Cheng Fang <[hidden email]> wrote:
A jberet user reported JBERET-29 (Foreign key constraint step_execution_jobexecutionid_fkey fails when using Postgresql on WildFly, and we are trying to fix it by jberet 1.0.0.Final.  The problem happens when user app starts a job within a transaction (e.g., CMT EJB), jberet inserts JobExecution into database (thread 1 & transaction 1), and then spawn a jberet-batch thread to run the job (thead 2 & transaction 2).  Sometimes T2 tries to access db before T1 is committed, hence the error reported by the user.

What's the common approach for solving this kind of problem?  I suppose other WildFly components may also have this issue and probably already solved.  Using transaction synchronization is a cleaner solution than polling db, but I'm not sure about its full implication.  Ideally, I don't want to use system level JTA API like TransactionManager or Synchronization in jberet proper, but probably we can implement it in WildFly jberet integration.

Thanks,
Cheng

_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev


_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

Scott Marlow
In reply to this post by Cheng Fang
What is it that you are trying to exactly?  Does thread 2 need to be
started only after a user app starts a job?  Or could thread 2 be from a
background pool that is waiting for a job to run?  Depending on what you
want to do, I think the answer is different.

On 02/04/2014 09:49 AM, Cheng Fang wrote:

> A jberet user reported JBERET-29
> <https://issues.jboss.org/browse/JBERET-29> (Foreign key constraint
> step_execution_jobexecutionid_fkey fails when using Postgresql on
> WildFly, and we are trying to fix it by jberet 1.0.0.Final.  The problem
> happens when user app starts a job within a transaction (e.g., CMT EJB),
> jberet inserts JobExecution into database (thread 1 & transaction 1),
> and then spawn a jberet-batch thread to run the job (thead 2 &
> transaction 2).  Sometimes T2 tries to access db before T1 is committed,
> hence the error reported by the user.
>
> What's the common approach for solving this kind of problem?  I suppose
> other WildFly components may also have this issue and probably already
> solved.  Using transaction synchronization is a cleaner solution than
> polling db, but I'm not sure about its full implication.  Ideally, I
> don't want to use system level JTA API like TransactionManager or
> Synchronization in jberet proper, but probably we can implement it in
> WildFly jberet integration.

If you want to create a thread after the JTA transaction completes, you
could key that off of the Synchronization.afterCompletion(Status).  See
http://docs.oracle.com/javaee/5/api/javax/transaction/TransactionSynchronizationRegistry.html

>
> Thanks,
> Cheng
>
>
> _______________________________________________
> wildfly-dev mailing list
> [hidden email]
> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>

_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

jtgreene
Administrator
In reply to this post by Cheng Fang
Does the spec require that JobExecution be tied to a CMT transaction? It sounds like it should not be. If you were to make this into a local transaction that is committed before the call to create the job completes, then you shouldn’t have that problem.
On Feb 4, 2014, at 8:49 AM, Cheng Fang <[hidden email]> wrote:

> A jberet user reported JBERET-29 (Foreign key constraint step_execution_jobexecutionid_fkey fails when using Postgresql on WildFly, and we are trying to fix it by jberet 1.0.0.Final.  The problem happens when user app starts a job within a transaction (e.g., CMT EJB), jberet inserts JobExecution into database (thread 1 & transaction 1), and then spawn a jberet-batch thread to run the job (thead 2 & transaction 2).  Sometimes T2 tries to access db before T1 is committed, hence the error reported by the user.
>
> What's the common approach for solving this kind of problem?  I suppose other WildFly components may also have this issue and probably already solved.  Using transaction synchronization is a cleaner solution than polling db, but I'm not sure about its full implication.  Ideally, I don't want to use system level JTA API like TransactionManager or Synchronization in jberet proper, but probably we can implement it in WildFly jberet integration.
>
> Thanks,
> Cheng
> _______________________________________________
> wildfly-dev mailing list
> [hidden email]
> https://lists.jboss.org/mailman/listinfo/wildfly-dev

--
Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat


_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

Scott Marlow
In reply to this post by Stuart Douglas
On 02/04/2014 09:57 AM, Stuart Douglas wrote:
> I would use a transaction synchronization, so you don't spawn the other
> thread until the transaction is successfully committed.
>
> What does the spec say about transactions? If a job is create in a
> thread that is part of a transaction and the transaction is rolled back
> should the job actually go ahead? Common sense would suggest not.

Good point, we should use the Synchronization.afterCompletion(Status)
and check if the Status parameter is STATUS_COMMITTED.

>
> Stuart
>
>
>
> On Tue, Feb 4, 2014 at 4:49 PM, Cheng Fang <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     A jberet user reported JBERET-29
>     <https://issues.jboss.org/browse/JBERET-29> (Foreign key constraint
>     step_execution_jobexecutionid_fkey fails when using Postgresql on
>     WildFly, and we are trying to fix it by jberet 1.0.0.Final.  The
>     problem happens when user app starts a job within a transaction
>     (e.g., CMT EJB), jberet inserts JobExecution into database (thread 1
>     & transaction 1), and then spawn a jberet-batch thread to run the
>     job (thead 2 & transaction 2).  Sometimes T2 tries to access db
>     before T1 is committed, hence the error reported by the user.
>
>     What's the common approach for solving this kind of problem?  I
>     suppose other WildFly components may also have this issue and
>     probably already solved.  Using transaction synchronization is a
>     cleaner solution than polling db, but I'm not sure about its full
>     implication.  Ideally, I don't want to use system level JTA API like
>     TransactionManager or Synchronization in jberet proper, but probably
>     we can implement it in WildFly jberet integration.
>
>     Thanks,
>     Cheng
>
>     _______________________________________________
>     wildfly-dev mailing list
>     [hidden email] <mailto:[hidden email]>
>     https://lists.jboss.org/mailman/listinfo/wildfly-dev
>
>
>
>
> _______________________________________________
> wildfly-dev mailing list
> [hidden email]
> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>

_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

Cheng Fang
In reply to this post by Stuart Douglas

On 2/4/14, 9:57 AM, Stuart Douglas wrote:
I would use a transaction synchronization, so you don't spawn the other thread until the transaction is successfully committed.

yes, we could implement it in wildfly-batch integration module.
What does the spec say about transactions? If a job is create in a thread that is part of a transaction and the transaction is rolled back should the job actually go ahead? Common sense would suggest not.
The transaction treatment in the batch spec is mostly around item processing, not much on how it interacts with the transaction in the running environment.  The only place that it touches on Java EE environment is section 9.7 Transactionality:

Chunk type check points are transactional. The batch runtime uses global transaction mode on the Java EE platform and local transaction mode on the Java SE platform. Global transaction timeout is configurable at step-level with a step-level property:

Yes, I agree if the batch client side transaction is rolled back, the job execution should not proceed.  With the current jberet impl, the job execution in this case will fail since the job repository is not in good state, like in the above bug.  If we have transaction syncrhonization in place, then the job will not start running till transaction 1 is committed.

Thanks,
Cheng

Stuart



On Tue, Feb 4, 2014 at 4:49 PM, Cheng Fang <[hidden email]> wrote:
A jberet user reported JBERET-29 (Foreign key constraint step_execution_jobexecutionid_fkey fails when using Postgresql on WildFly, and we are trying to fix it by jberet 1.0.0.Final.  The problem happens when user app starts a job within a transaction (e.g., CMT EJB), jberet inserts JobExecution into database (thread 1 & transaction 1), and then spawn a jberet-batch thread to run the job (thead 2 & transaction 2).  Sometimes T2 tries to access db before T1 is committed, hence the error reported by the user.

What's the common approach for solving this kind of problem?  I suppose other WildFly components may also have this issue and probably already solved.  Using transaction synchronization is a cleaner solution than polling db, but I'm not sure about its full implication.  Ideally, I don't want to use system level JTA API like TransactionManager or Synchronization in jberet proper, but probably we can implement it in WildFly jberet integration.

Thanks,
Cheng

_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev



_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

Cheng Fang
In reply to this post by Scott Marlow

On 2/4/14, 10:09 AM, Scott Marlow wrote:
> What is it that you are trying to exactly?  Does thread 2 need to be
> started only after a user app starts a job?  Or could thread 2 be from
> a background pool that is waiting for a job to run? Depending on what
> you want to do, I think the answer is different.
>
the job execution task needs to be submitted to execution service as
part of transaction/thread 1.  So I guess we could buffer up the
submitted task and don't actually submit it to the underlying execution
service till afterCompletion is called with committed status.  I think
we can achieve that in wildfly-batch integration module.  Will check
with James.

Thanks,
Cheng

> On 02/04/2014 09:49 AM, Cheng Fang wrote:
>> A jberet user reported JBERET-29
>> <https://issues.jboss.org/browse/JBERET-29> (Foreign key constraint
>> step_execution_jobexecutionid_fkey fails when using Postgresql on
>> WildFly, and we are trying to fix it by jberet 1.0.0.Final.  The problem
>> happens when user app starts a job within a transaction (e.g., CMT EJB),
>> jberet inserts JobExecution into database (thread 1 & transaction 1),
>> and then spawn a jberet-batch thread to run the job (thead 2 &
>> transaction 2).  Sometimes T2 tries to access db before T1 is committed,
>> hence the error reported by the user.
>>
>> What's the common approach for solving this kind of problem?  I suppose
>> other WildFly components may also have this issue and probably already
>> solved.  Using transaction synchronization is a cleaner solution than
>> polling db, but I'm not sure about its full implication. Ideally, I
>> don't want to use system level JTA API like TransactionManager or
>> Synchronization in jberet proper, but probably we can implement it in
>> WildFly jberet integration.
>
> If you want to create a thread after the JTA transaction completes,
> you could key that off of the
> Synchronization.afterCompletion(Status).  See
> http://docs.oracle.com/javaee/5/api/javax/transaction/TransactionSynchronizationRegistry.html
>
>>
>> Thanks,
>> Cheng
>>
>>
>> _______________________________________________
>> wildfly-dev mailing list
>> [hidden email]
>> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>>
>

_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

jtgreene
Administrator
In reply to this post by Cheng Fang

On Feb 4, 2014, at 9:56 AM, Cheng Fang <[hidden email]> wrote:

>
> On 2/4/14, 9:57 AM, Stuart Douglas wrote:
>> I would use a transaction synchronization, so you don't spawn the other thread until the transaction is successfully committed.
>>
> yes, we could implement it in wildfly-batch integration module.
>> What does the spec say about transactions? If a job is create in a thread that is part of a transaction and the transaction is rolled back should the job actually go ahead? Common sense would suggest not.
> The transaction treatment in the batch spec is mostly around item processing, not much on how it interacts with the transaction in the running environment.  The only place that it touches on Java EE environment is section 9.7 Transactionality:
>
> Chunk type check points are transactional. The batch runtime uses global transaction mode on the Java EE platform and local transaction mode on the Java SE platform. Global transaction timeout is configurable at step-level with a step-level property:
>
> Yes, I agree if the batch client side transaction is rolled back, the job execution should not proceed.  With the current jberet impl, the job execution in this case will fail since the job repository is not in good state, like in the above bug.  If we have transaction syncrhonization in place, then the job will not start running till transaction 1 is committed.

There is a consistency problem here though. If you expect the client side to rollback on transaction failure, then the in-memory job store should as well. IMO before committing to such a big feature, I would recommend looking at what the RI does here. If the spec doesn’t describe it, and the RI doesn’t do it, then we should avoid investing time on it at least right now where we really need to get WF8 out the door.

--
Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat


_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

Cheng Fang
In reply to this post by jtgreene

On 2/4/14, 10:11 AM, Jason Greene wrote:
> Does the spec require that JobExecution be tied to a CMT transaction?
No.
> It sounds like it should not be. If you were to make this into a local transaction that is committed before the call to create the job completes, then you shouldn’t have that problem.
Are you saying with local transaction, it can access uncommitted data
from another transaction?  In this case, JobExecution is still not
committed when it's accessed via foreign key by transaction 2.

Inside WildFly, we just look up and use UserTransaction to demarcate all
transactions, and it seems a bit odd to use local transaction just for
this case.  The batch spec does require the use of global transaction on
Java EE platform.

Cheng

> On Feb 4, 2014, at 8:49 AM, Cheng Fang <[hidden email]> wrote:
>
>> A jberet user reported JBERET-29 (Foreign key constraint step_execution_jobexecutionid_fkey fails when using Postgresql on WildFly, and we are trying to fix it by jberet 1.0.0.Final.  The problem happens when user app starts a job within a transaction (e.g., CMT EJB), jberet inserts JobExecution into database (thread 1 & transaction 1), and then spawn a jberet-batch thread to run the job (thead 2 & transaction 2).  Sometimes T2 tries to access db before T1 is committed, hence the error reported by the user.
>>
>> What's the common approach for solving this kind of problem?  I suppose other WildFly components may also have this issue and probably already solved.  Using transaction synchronization is a cleaner solution than polling db, but I'm not sure about its full implication.  Ideally, I don't want to use system level JTA API like TransactionManager or Synchronization in jberet proper, but probably we can implement it in WildFly jberet integration.
>>
>> Thanks,
>> Cheng
>> _______________________________________________
>> wildfly-dev mailing list
>> [hidden email]
>> https://lists.jboss.org/mailman/listinfo/wildfly-dev
> --
> Jason T. Greene
> WildFly Lead / JBoss EAP Platform Architect
> JBoss, a division of Red Hat
>

_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

James Perkins
In reply to this post by jtgreene

On 02/04/2014 08:16 AM, Jason Greene wrote:

> On Feb 4, 2014, at 9:56 AM, Cheng Fang <[hidden email]> wrote:
>
>> On 2/4/14, 9:57 AM, Stuart Douglas wrote:
>>> I would use a transaction synchronization, so you don't spawn the other thread until the transaction is successfully committed.
>>>
>> yes, we could implement it in wildfly-batch integration module.
>>> What does the spec say about transactions? If a job is create in a thread that is part of a transaction and the transaction is rolled back should the job actually go ahead? Common sense would suggest not.
>> The transaction treatment in the batch spec is mostly around item processing, not much on how it interacts with the transaction in the running environment.  The only place that it touches on Java EE environment is section 9.7 Transactionality:
>>
>> Chunk type check points are transactional. The batch runtime uses global transaction mode on the Java EE platform and local transaction mode on the Java SE platform. Global transaction timeout is configurable at step-level with a step-level property:
>>
>> Yes, I agree if the batch client side transaction is rolled back, the job execution should not proceed.  With the current jberet impl, the job execution in this case will fail since the job repository is not in good state, like in the above bug.  If we have transaction syncrhonization in place, then the job will not start running till transaction 1 is committed.
> There is a consistency problem here though. If you expect the client side to rollback on transaction failure, then the in-memory job store should as well. IMO before committing to such a big feature, I would recommend looking at what the RI does here. If the spec doesn’t describe it, and the RI doesn’t do it, then we should avoid investing time on it at least right now where we really need to get WF8 out the door.
I don't see in the spec where it requires any kind of transaction around
a job repository. In fact the spec states "Note the implementation of
the job repository is outside the scope of this specification.".

The RI does have a JDBC repository, but it doesn't insert anything into
the tables in a transaction.

If we're only seeing this in PostgreSQL and a workaround with putting
JobOperator.start() outside a transaction works, I would suggest that's
okay for now. I do agree it needs to be fixed, but we might want to look
at how we're handling transaction in JBeret as a whole. The RI, not that
I want to model anything after it, uses it's own
TransactionManagerAdapter. It might make sense for JBeret to use a
TransactionManager rather than a UserTransaction. Or put the ownness on
the SPI implementation of the BatchEnvironment to handle the transactions.

>
> --
> Jason T. Greene
> WildFly Lead / JBoss EAP Platform Architect
> JBoss, a division of Red Hat
>
>
> _______________________________________________
> wildfly-dev mailing list
> [hidden email]
> https://lists.jboss.org/mailman/listinfo/wildfly-dev

--
James R. Perkins
Red Hat JBoss Middleware

_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

Scott Marlow
On 02/04/2014 02:42 PM, James R. Perkins wrote:

>
> On 02/04/2014 08:16 AM, Jason Greene wrote:
>> On Feb 4, 2014, at 9:56 AM, Cheng Fang <[hidden email]> wrote:
>>
>>> On 2/4/14, 9:57 AM, Stuart Douglas wrote:
>>>> I would use a transaction synchronization, so you don't spawn the other thread until the transaction is successfully committed.
>>>>
>>> yes, we could implement it in wildfly-batch integration module.
>>>> What does the spec say about transactions? If a job is create in a thread that is part of a transaction and the transaction is rolled back should the job actually go ahead? Common sense would suggest not.
>>> The transaction treatment in the batch spec is mostly around item processing, not much on how it interacts with the transaction in the running environment.  The only place that it touches on Java EE environment is section 9.7 Transactionality:
>>>
>>> Chunk type check points are transactional. The batch runtime uses global transaction mode on the Java EE platform and local transaction mode on the Java SE platform. Global transaction timeout is configurable at step-level with a step-level property:
>>>
>>> Yes, I agree if the batch client side transaction is rolled back, the job execution should not proceed.  With the current jberet impl, the job execution in this case will fail since the job repository is not in good state, like in the above bug.  If we have transaction syncrhonization in place, then the job will not start running till transaction 1 is committed.
>> There is a consistency problem here though. If you expect the client side to rollback on transaction failure, then the in-memory job store should as well. IMO before committing to such a big feature, I would recommend looking at what the RI does here. If the spec doesn’t describe it, and the RI doesn’t do it, then we should avoid investing time on it at least right now where we really need to get WF8 out the door.
> I don't see in the spec where it requires any kind of transaction around
> a job repository. In fact the spec states "Note the implementation of
> the job repository is outside the scope of this specification.".
>
> The RI does have a JDBC repository, but it doesn't insert anything into
> the tables in a transaction.
>
> If we're only seeing this in PostgreSQL and a workaround with putting
> JobOperator.start() outside a transaction works, I would suggest that's
> okay for now. I do agree it needs to be fixed, but we might want to look
> at how we're handling transaction in JBeret as a whole. The RI, not that
> I want to model anything after it, uses it's own
> TransactionManagerAdapter. It might make sense for JBeret to use a
> TransactionManager rather than a UserTransaction. Or put the ownness on
> the SPI implementation of the BatchEnvironment to handle the transactions.

Are you saying that the application should work around this by calling a
different bean method that is marked NOT_SUPPORTED to facilitate
suspending the JTA transaction?

>>
>> --
>> Jason T. Greene
>> WildFly Lead / JBoss EAP Platform Architect
>> JBoss, a division of Red Hat
>>
>>
>> _______________________________________________
>> wildfly-dev mailing list
>> [hidden email]
>> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>

_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

jtgreene
Administrator
In reply to this post by Cheng Fang

On Feb 4, 2014, at 10:28 AM, Cheng Fang <[hidden email]> wrote:

>
> On 2/4/14, 10:11 AM, Jason Greene wrote:
>> Does the spec require that JobExecution be tied to a CMT transaction?
> No.
>> It sounds like it should not be. If you were to make this into a local transaction that is committed before the call to create the job completes, then you shouldn’t have that problem.
> Are you saying with local transaction, it can access uncommitted data
> from another transaction?  In this case, JobExecution is still not
> committed when it's accessed via foreign key by transaction 2.

The behavior I was basically describing is that in thread 1 you suspend the current transaction, start a new one, write the data and commit. After the commit has completed you fork thread 2 which will see thread 1’s write. This is semantically equivalent to the current behavior of your memory store, or even a future file system store.

>
> Inside WildFly, we just look up and use UserTransaction to demarcate all
> transactions, and it seems a bit odd to use local transaction just for
> this case.  The batch spec does require the use of global transaction on
> Java EE platform.

I think it depends on whether the batch client is viewed as a transactional participate, if it is then things get a lot more complicated. As an example, if you are using a file system store, or an in memory store, you need to actually have the ability to rollback if the transaction fails. This requires either developing an XAResource (like JMS has to do) or using a synchronization as a sloppy rollback mechanism. (In the JDBC case you don’t need it though, since JCA already manages this).

>
> Cheng
>> On Feb 4, 2014, at 8:49 AM, Cheng Fang <[hidden email]> wrote:
>>
>>> A jberet user reported JBERET-29 (Foreign key constraint step_execution_jobexecutionid_fkey fails when using Postgresql on WildFly, and we are trying to fix it by jberet 1.0.0.Final.  The problem happens when user app starts a job within a transaction (e.g., CMT EJB), jberet inserts JobExecution into database (thread 1 & transaction 1), and then spawn a jberet-batch thread to run the job (thead 2 & transaction 2).  Sometimes T2 tries to access db before T1 is committed, hence the error reported by the user.
>>>
>>> What's the common approach for solving this kind of problem?  I suppose other WildFly components may also have this issue and probably already solved.  Using transaction synchronization is a cleaner solution than polling db, but I'm not sure about its full implication.  Ideally, I don't want to use system level JTA API like TransactionManager or Synchronization in jberet proper, but probably we can implement it in WildFly jberet integration.
>>>
>>> Thanks,
>>> Cheng
>>> _______________________________________________
>>> wildfly-dev mailing list
>>> [hidden email]
>>> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>> --
>> Jason T. Greene
>> WildFly Lead / JBoss EAP Platform Architect
>> JBoss, a division of Red Hat
>>
>
> _______________________________________________
> wildfly-dev mailing list
> [hidden email]
> https://lists.jboss.org/mailman/listinfo/wildfly-dev

--
Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat


_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

James Perkins
In reply to this post by Scott Marlow

On 02/04/2014 12:40 PM, Scott Marlow wrote:

> On 02/04/2014 02:42 PM, James R. Perkins wrote:
>>
>> On 02/04/2014 08:16 AM, Jason Greene wrote:
>>> On Feb 4, 2014, at 9:56 AM, Cheng Fang <[hidden email]> wrote:
>>>
>>>> On 2/4/14, 9:57 AM, Stuart Douglas wrote:
>>>>> I would use a transaction synchronization, so you don't spawn the
>>>>> other thread until the transaction is successfully committed.
>>>>>
>>>> yes, we could implement it in wildfly-batch integration module.
>>>>> What does the spec say about transactions? If a job is create in a
>>>>> thread that is part of a transaction and the transaction is rolled
>>>>> back should the job actually go ahead? Common sense would suggest
>>>>> not.
>>>> The transaction treatment in the batch spec is mostly around item
>>>> processing, not much on how it interacts with the transaction in
>>>> the running environment.  The only place that it touches on Java EE
>>>> environment is section 9.7 Transactionality:
>>>>
>>>> Chunk type check points are transactional. The batch runtime uses
>>>> global transaction mode on the Java EE platform and local
>>>> transaction mode on the Java SE platform. Global transaction
>>>> timeout is configurable at step-level with a step-level property:
>>>>
>>>> Yes, I agree if the batch client side transaction is rolled back,
>>>> the job execution should not proceed.  With the current jberet
>>>> impl, the job execution in this case will fail since the job
>>>> repository is not in good state, like in the above bug.  If we have
>>>> transaction syncrhonization in place, then the job will not start
>>>> running till transaction 1 is committed.
>>> There is a consistency problem here though. If you expect the client
>>> side to rollback on transaction failure, then the in-memory job
>>> store should as well. IMO before committing to such a big feature, I
>>> would recommend looking at what the RI does here. If the spec
>>> doesn’t describe it, and the RI doesn’t do it, then we should avoid
>>> investing time on it at least right now where we really need to get
>>> WF8 out the door.
>> I don't see in the spec where it requires any kind of transaction around
>> a job repository. In fact the spec states "Note the implementation of
>> the job repository is outside the scope of this specification.".
>>
>> The RI does have a JDBC repository, but it doesn't insert anything into
>> the tables in a transaction.
>>
>> If we're only seeing this in PostgreSQL and a workaround with putting
>> JobOperator.start() outside a transaction works, I would suggest that's
>> okay for now. I do agree it needs to be fixed, but we might want to look
>> at how we're handling transaction in JBeret as a whole. The RI, not that
>> I want to model anything after it, uses it's own
>> TransactionManagerAdapter. It might make sense for JBeret to use a
>> TransactionManager rather than a UserTransaction. Or put the ownness on
>> the SPI implementation of the BatchEnvironment to handle the
>> transactions.
>
> Are you saying that the application should work around this by calling
> a different bean method that is marked NOT_SUPPORTED to facilitate
> suspending the JTA transaction?
No I'm just saying they need to invoke the JobOperator.start() outside a
transaction. At least from my understand on the JIRA that seems to
workaround the issue. I will admit to not fully looking into this in
detail though ;)

>>>
>>> --
>>> Jason T. Greene
>>> WildFly Lead / JBoss EAP Platform Architect
>>> JBoss, a division of Red Hat
>>>
>>>
>>> _______________________________________________
>>> wildfly-dev mailing list
>>> [hidden email]
>>> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>>
>

--
James R. Perkins
Red Hat JBoss Middleware

_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

jtgreene
Administrator

On Feb 4, 2014, at 3:01 PM, James R. Perkins <[hidden email]> wrote:

>
> On 02/04/2014 12:40 PM, Scott Marlow wrote:
>> On 02/04/2014 02:42 PM, James R. Perkins wrote:
>>>
>>> On 02/04/2014 08:16 AM, Jason Greene wrote:
>>>> On Feb 4, 2014, at 9:56 AM, Cheng Fang <[hidden email]> wrote:
>>>>
>>>>> On 2/4/14, 9:57 AM, Stuart Douglas wrote:
>>>>>> I would use a transaction synchronization, so you don't spawn the other thread until the transaction is successfully committed.
>>>>>>
>>>>> yes, we could implement it in wildfly-batch integration module.
>>>>>> What does the spec say about transactions? If a job is create in a thread that is part of a transaction and the transaction is rolled back should the job actually go ahead? Common sense would suggest not.
>>>>> The transaction treatment in the batch spec is mostly around item processing, not much on how it interacts with the transaction in the running environment.  The only place that it touches on Java EE environment is section 9.7 Transactionality:
>>>>>
>>>>> Chunk type check points are transactional. The batch runtime uses global transaction mode on the Java EE platform and local transaction mode on the Java SE platform. Global transaction timeout is configurable at step-level with a step-level property:
>>>>>
>>>>> Yes, I agree if the batch client side transaction is rolled back, the job execution should not proceed.  With the current jberet impl, the job execution in this case will fail since the job repository is not in good state, like in the above bug.  If we have transaction syncrhonization in place, then the job will not start running till transaction 1 is committed.
>>>> There is a consistency problem here though. If you expect the client side to rollback on transaction failure, then the in-memory job store should as well. IMO before committing to such a big feature, I would recommend looking at what the RI does here. If the spec doesn’t describe it, and the RI doesn’t do it, then we should avoid investing time on it at least right now where we really need to get WF8 out the door.
>>> I don't see in the spec where it requires any kind of transaction around
>>> a job repository. In fact the spec states "Note the implementation of
>>> the job repository is outside the scope of this specification.".
>>>
>>> The RI does have a JDBC repository, but it doesn't insert anything into
>>> the tables in a transaction.
>>>
>>> If we're only seeing this in PostgreSQL and a workaround with putting
>>> JobOperator.start() outside a transaction works, I would suggest that's
>>> okay for now. I do agree it needs to be fixed, but we might want to look
>>> at how we're handling transaction in JBeret as a whole. The RI, not that
>>> I want to model anything after it, uses it's own
>>> TransactionManagerAdapter. It might make sense for JBeret to use a
>>> TransactionManager rather than a UserTransaction. Or put the ownness on
>>> the SPI implementation of the BatchEnvironment to handle the transactions.
>>
>> Are you saying that the application should work around this by calling a different bean method that is marked NOT_SUPPORTED to facilitate suspending the JTA transaction?
> No I'm just saying they need to invoke the JobOperator.start() outside a transaction. At least from my understand on the JIRA that seems to workaround the issue. I will admit to not fully looking into this in detail though ;)

That would be silly :)

--
Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat


_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

jtgreene
Administrator

On Feb 4, 2014, at 3:13 PM, Jason Greene <[hidden email]> wrote:

>
> On Feb 4, 2014, at 3:01 PM, James R. Perkins <[hidden email]> wrote:
>
>>
>> On 02/04/2014 12:40 PM, Scott Marlow wrote:
>>> On 02/04/2014 02:42 PM, James R. Perkins wrote:
>>>>
>>>> On 02/04/2014 08:16 AM, Jason Greene wrote:
>>>>> On Feb 4, 2014, at 9:56 AM, Cheng Fang <[hidden email]> wrote:
>>>>>
>>>>>> On 2/4/14, 9:57 AM, Stuart Douglas wrote:
>>>>>>> I would use a transaction synchronization, so you don't spawn the other thread until the transaction is successfully committed.
>>>>>>>
>>>>>> yes, we could implement it in wildfly-batch integration module.
>>>>>>> What does the spec say about transactions? If a job is create in a thread that is part of a transaction and the transaction is rolled back should the job actually go ahead? Common sense would suggest not.
>>>>>> The transaction treatment in the batch spec is mostly around item processing, not much on how it interacts with the transaction in the running environment.  The only place that it touches on Java EE environment is section 9.7 Transactionality:
>>>>>>
>>>>>> Chunk type check points are transactional. The batch runtime uses global transaction mode on the Java EE platform and local transaction mode on the Java SE platform. Global transaction timeout is configurable at step-level with a step-level property:
>>>>>>
>>>>>> Yes, I agree if the batch client side transaction is rolled back, the job execution should not proceed.  With the current jberet impl, the job execution in this case will fail since the job repository is not in good state, like in the above bug.  If we have transaction syncrhonization in place, then the job will not start running till transaction 1 is committed.
>>>>> There is a consistency problem here though. If you expect the client side to rollback on transaction failure, then the in-memory job store should as well. IMO before committing to such a big feature, I would recommend looking at what the RI does here. If the spec doesn’t describe it, and the RI doesn’t do it, then we should avoid investing time on it at least right now where we really need to get WF8 out the door.
>>>> I don't see in the spec where it requires any kind of transaction around
>>>> a job repository. In fact the spec states "Note the implementation of
>>>> the job repository is outside the scope of this specification.".
>>>>
>>>> The RI does have a JDBC repository, but it doesn't insert anything into
>>>> the tables in a transaction.
>>>>
>>>> If we're only seeing this in PostgreSQL and a workaround with putting
>>>> JobOperator.start() outside a transaction works, I would suggest that's
>>>> okay for now. I do agree it needs to be fixed, but we might want to look
>>>> at how we're handling transaction in JBeret as a whole. The RI, not that
>>>> I want to model anything after it, uses it's own
>>>> TransactionManagerAdapter. It might make sense for JBeret to use a
>>>> TransactionManager rather than a UserTransaction. Or put the ownness on
>>>> the SPI implementation of the BatchEnvironment to handle the transactions.
>>>
>>> Are you saying that the application should work around this by calling a different bean method that is marked NOT_SUPPORTED to facilitate suspending the JTA transaction?
>> No I'm just saying they need to invoke the JobOperator.start() outside a transaction. At least from my understand on the JIRA that seems to workaround the issue. I will admit to not fully looking into this in detail though ;)
>
> That would be silly :)

Requiring a NOT_SUPPORTED method that is. It’s pretty easy for JBeret to isolate the transaction if it wanted to

tx = TransactionManager.suspend()
TransactionManager.begin()
// write the record
TransactionManager.commit()
TransactionManager.resume(tx);

--
Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat


_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

Scott Marlow
On 02/04/2014 04:16 PM, Jason Greene wrote:

>
> On Feb 4, 2014, at 3:13 PM, Jason Greene <[hidden email]> wrote:
>
>>
>> On Feb 4, 2014, at 3:01 PM, James R. Perkins <[hidden email]> wrote:
>>
>>>
>>> On 02/04/2014 12:40 PM, Scott Marlow wrote:
>>>> On 02/04/2014 02:42 PM, James R. Perkins wrote:
>>>>>
>>>>> On 02/04/2014 08:16 AM, Jason Greene wrote:
>>>>>> On Feb 4, 2014, at 9:56 AM, Cheng Fang <[hidden email]> wrote:
>>>>>>
>>>>>>> On 2/4/14, 9:57 AM, Stuart Douglas wrote:
>>>>>>>> I would use a transaction synchronization, so you don't spawn the other thread until the transaction is successfully committed.
>>>>>>>>
>>>>>>> yes, we could implement it in wildfly-batch integration module.
>>>>>>>> What does the spec say about transactions? If a job is create in a thread that is part of a transaction and the transaction is rolled back should the job actually go ahead? Common sense would suggest not.
>>>>>>> The transaction treatment in the batch spec is mostly around item processing, not much on how it interacts with the transaction in the running environment.  The only place that it touches on Java EE environment is section 9.7 Transactionality:
>>>>>>>
>>>>>>> Chunk type check points are transactional. The batch runtime uses global transaction mode on the Java EE platform and local transaction mode on the Java SE platform. Global transaction timeout is configurable at step-level with a step-level property:
>>>>>>>
>>>>>>> Yes, I agree if the batch client side transaction is rolled back, the job execution should not proceed.  With the current jberet impl, the job execution in this case will fail since the job repository is not in good state, like in the above bug.  If we have transaction syncrhonization in place, then the job will not start running till transaction 1 is committed.
>>>>>> There is a consistency problem here though. If you expect the client side to rollback on transaction failure, then the in-memory job store should as well. IMO before committing to such a big feature, I would recommend looking at what the RI does here. If the spec doesn’t describe it, and the RI doesn’t do it, then we should avoid investing time on it at least right now where we really need to get WF8 out the door.
>>>>> I don't see in the spec where it requires any kind of transaction around
>>>>> a job repository. In fact the spec states "Note the implementation of
>>>>> the job repository is outside the scope of this specification.".
>>>>>
>>>>> The RI does have a JDBC repository, but it doesn't insert anything into
>>>>> the tables in a transaction.
>>>>>
>>>>> If we're only seeing this in PostgreSQL and a workaround with putting
>>>>> JobOperator.start() outside a transaction works, I would suggest that's
>>>>> okay for now. I do agree it needs to be fixed, but we might want to look
>>>>> at how we're handling transaction in JBeret as a whole. The RI, not that
>>>>> I want to model anything after it, uses it's own
>>>>> TransactionManagerAdapter. It might make sense for JBeret to use a
>>>>> TransactionManager rather than a UserTransaction. Or put the ownness on
>>>>> the SPI implementation of the BatchEnvironment to handle the transactions.
>>>>
>>>> Are you saying that the application should work around this by calling a different bean method that is marked NOT_SUPPORTED to facilitate suspending the JTA transaction?
>>> No I'm just saying they need to invoke the JobOperator.start() outside a transaction. At least from my understand on the JIRA that seems to workaround the issue. I will admit to not fully looking into this in detail though ;)
>>
>> That would be silly :)
Logically it would be the same as us suspending the TX/starting the job
and resuming the TX.  I agree that its silly for the application to have
to worry about suspending the tx, better if we handle this.

I'm just not sure which approach is better.  If the started job depends
on application changes that aren't written to the database until the
container managed transaction ends successfully, that could be a
surprise to have the job start early.

I agree, that if the started job, doesn't have a dependency on the CMT
ending, just suspendingTx/startingJb/resumingTx is best.

If the started job has a dependency on the CMT, could we have an
extension property that specifies that (so we could defer starting the
job when the tx completes successfully).

>
> Requiring a NOT_SUPPORTED method that is. It’s pretty easy for JBeret to isolate the transaction if it wanted to
>
> tx = TransactionManager.suspend()
> TransactionManager.begin()
> // write the record
> TransactionManager.commit()
> TransactionManager.resume(tx);
>
> --
> Jason T. Greene
> WildFly Lead / JBoss EAP Platform Architect
> JBoss, a division of Red Hat
>
>
> _______________________________________________
> wildfly-dev mailing list
> [hidden email]
> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>

_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

CMT Batch Puzzle (Was Re: [Transaction synchronization between threads])

jtgreene
Administrator
In reply to this post by James Perkins

On Feb 4, 2014, at 1:42 PM, James R. Perkins <[hidden email]> wrote:

> I don't see in the spec where it requires any kind of transaction around a job repository. In fact the spec states "Note the implementation of the job repository is outside the scope of this specification.".
>
> The RI does have a JDBC repository, but it doesn't insert anything into the tables in a transaction.
>
> If we're only seeing this in PostgreSQL and a workaround with putting JobOperator.start() outside a transaction works, I would suggest that's okay for now. I do agree it needs to be fixed, but we might want to look at how we're handling transaction in JBeret as a whole. The RI, not that I want to model anything after it, uses it's own TransactionManagerAdapter. It might make sense for JBeret to use a TransactionManager rather than a UserTransaction. Or put the ownness on the SPI implementation of the BatchEnvironment to handle the transactions.

Good points; and this brings me to my pathological batch puzzle. What does this code do:

// Default gets transaction required
String doStuff() {  
    long execID = jobOperator.start("simplejob", props);
    BatchStatus status = jobOperator.getJobExecution(execID).getBatchStatus()
    while (status != COMMITTED && status != FAILED && status != ABANDONED) {
        Thread.sleep(1000);  
    }
    return status.toString();
}

--
Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat


_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

Radoslaw Rodak
In reply to this post by jtgreene
Hi


Am 04.02.2014 um 22:16 schrieb Jason Greene <[hidden email]>:

>
> On Feb 4, 2014, at 3:13 PM, Jason Greene <[hidden email]> wrote:
>
>>
>> On Feb 4, 2014, at 3:01 PM, James R. Perkins <[hidden email]> wrote:
>>
>>>
>>> On 02/04/2014 12:40 PM, Scott Marlow wrote:
>>>> On 02/04/2014 02:42 PM, James R. Perkins wrote:
>>>>>
>>>>> On 02/04/2014 08:16 AM, Jason Greene wrote:
>>>>>> On Feb 4, 2014, at 9:56 AM, Cheng Fang <[hidden email]> wrote:
>>>>>>
>>>>>>> On 2/4/14, 9:57 AM, Stuart Douglas wrote:
>>>>>>>> I would use a transaction synchronization, so you don't spawn the other thread until the transaction is successfully committed.
>>>>>>>>
>>>>>>> yes, we could implement it in wildfly-batch integration module.
>>>>>>>> What does the spec say about transactions? If a job is create in a thread that is part of a transaction and the transaction is rolled back should the job actually go ahead? Common sense would suggest not.
>>>>>>> The transaction treatment in the batch spec is mostly around item processing, not much on how it interacts with the transaction in the running environment.  The only place that it touches on Java EE environment is section 9.7 Transactionality:
>>>>>>>
>>>>>>> Chunk type check points are transactional. The batch runtime uses global transaction mode on the Java EE platform and local transaction mode on the Java SE platform. Global transaction timeout is configurable at step-level with a step-level property:
>>>>>>>
>>>>>>> Yes, I agree if the batch client side transaction is rolled back, the job execution should not proceed.  With the current jberet impl, the job execution in this case will fail since the job repository is not in good state, like in the above bug.  If we have transaction syncrhonization in place, then the job will not start running till transaction 1 is committed.
>>>>>> There is a consistency problem here though. If you expect the client side to rollback on transaction failure, then the in-memory job store should as well. IMO before committing to such a big feature, I would recommend looking at what the RI does here. If the spec doesn’t describe it, and the RI doesn’t do it, then we should avoid investing time on it at least right now where we really need to get WF8 out the door.
>>>>> I don't see in the spec where it requires any kind of transaction around
>>>>> a job repository. In fact the spec states "Note the implementation of
>>>>> the job repository is outside the scope of this specification.".
>>>>>
>>>>> The RI does have a JDBC repository, but it doesn't insert anything into
>>>>> the tables in a transaction.
>>>>>
>>>>> If we're only seeing this in PostgreSQL and a workaround with putting
>>>>> JobOperator.start() outside a transaction works, I would suggest that's
>>>>> okay for now. I do agree it needs to be fixed, but we might want to look
>>>>> at how we're handling transaction in JBeret as a whole. The RI, not that
>>>>> I want to model anything after it, uses it's own
>>>>> TransactionManagerAdapter. It might make sense for JBeret to use a
>>>>> TransactionManager rather than a UserTransaction. Or put the ownness on
>>>>> the SPI implementation of the BatchEnvironment to handle the transactions.
>>>>
>>>> Are you saying that the application should work around this by calling a different bean method that is marked NOT_SUPPORTED to facilitate suspending the JTA transaction?
>>> No I'm just saying they need to invoke the JobOperator.start() outside a transaction. At least from my understand on the JIRA that seems to workaround the issue. I will admit to not fully looking into this in detail though ;)
>>
>> That would be silly :)
>
> Requiring a NOT_SUPPORTED method that is. It’s pretty easy for JBeret to isolate the transaction if it wanted to
>
> tx = TransactionManager.suspend()
> TransactionManager.begin()
> // write the record
> TransactionManager.commit()
> TransactionManager.resume(tx);
>

What will happened to suspended Transaction when you get Exception on TransactionManager.commit() ?




_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: Transaction synchronization between threads

jtgreene
Administrator

On Feb 4, 2014, at 3:51 PM, Radoslaw Rodak <[hidden email]> wrote:

> Hi
>
>
> Am 04.02.2014 um 22:16 schrieb Jason Greene <[hidden email]>:
>
>>
>> On Feb 4, 2014, at 3:13 PM, Jason Greene <[hidden email]> wrote:
>>
>>>
>>> On Feb 4, 2014, at 3:01 PM, James R. Perkins <[hidden email]> wrote:
>>>
>>>>
>>>> On 02/04/2014 12:40 PM, Scott Marlow wrote:
>>>>> On 02/04/2014 02:42 PM, James R. Perkins wrote:
>>>>>>
>>>>>> On 02/04/2014 08:16 AM, Jason Greene wrote:
>>>>>>> On Feb 4, 2014, at 9:56 AM, Cheng Fang <[hidden email]> wrote:
>>>>>>>
>>>>>>>> On 2/4/14, 9:57 AM, Stuart Douglas wrote:
>>>>>>>>> I would use a transaction synchronization, so you don't spawn the other thread until the transaction is successfully committed.
>>>>>>>>>
>>>>>>>> yes, we could implement it in wildfly-batch integration module.
>>>>>>>>> What does the spec say about transactions? If a job is create in a thread that is part of a transaction and the transaction is rolled back should the job actually go ahead? Common sense would suggest not.
>>>>>>>> The transaction treatment in the batch spec is mostly around item processing, not much on how it interacts with the transaction in the running environment.  The only place that it touches on Java EE environment is section 9.7 Transactionality:
>>>>>>>>
>>>>>>>> Chunk type check points are transactional. The batch runtime uses global transaction mode on the Java EE platform and local transaction mode on the Java SE platform. Global transaction timeout is configurable at step-level with a step-level property:
>>>>>>>>
>>>>>>>> Yes, I agree if the batch client side transaction is rolled back, the job execution should not proceed.  With the current jberet impl, the job execution in this case will fail since the job repository is not in good state, like in the above bug.  If we have transaction syncrhonization in place, then the job will not start running till transaction 1 is committed.
>>>>>>> There is a consistency problem here though. If you expect the client side to rollback on transaction failure, then the in-memory job store should as well. IMO before committing to such a big feature, I would recommend looking at what the RI does here. If the spec doesn’t describe it, and the RI doesn’t do it, then we should avoid investing time on it at least right now where we really need to get WF8 out the door.
>>>>>> I don't see in the spec where it requires any kind of transaction around
>>>>>> a job repository. In fact the spec states "Note the implementation of
>>>>>> the job repository is outside the scope of this specification.".
>>>>>>
>>>>>> The RI does have a JDBC repository, but it doesn't insert anything into
>>>>>> the tables in a transaction.
>>>>>>
>>>>>> If we're only seeing this in PostgreSQL and a workaround with putting
>>>>>> JobOperator.start() outside a transaction works, I would suggest that's
>>>>>> okay for now. I do agree it needs to be fixed, but we might want to look
>>>>>> at how we're handling transaction in JBeret as a whole. The RI, not that
>>>>>> I want to model anything after it, uses it's own
>>>>>> TransactionManagerAdapter. It might make sense for JBeret to use a
>>>>>> TransactionManager rather than a UserTransaction. Or put the ownness on
>>>>>> the SPI implementation of the BatchEnvironment to handle the transactions.
>>>>>
>>>>> Are you saying that the application should work around this by calling a different bean method that is marked NOT_SUPPORTED to facilitate suspending the JTA transaction?
>>>> No I'm just saying they need to invoke the JobOperator.start() outside a transaction. At least from my understand on the JIRA that seems to workaround the issue. I will admit to not fully looking into this in detail though ;)
>>>
>>> That would be silly :)
>>
>> Requiring a NOT_SUPPORTED method that is. It’s pretty easy for JBeret to isolate the transaction if it wanted to
>>
>> tx = TransactionManager.suspend()
>> TransactionManager.begin()
>> // write the record
>> TransactionManager.commit()
>> TransactionManager.resume(tx);
>>
>
> What will happened to suspended Transaction when you get Exception on TransactionManager.commit() ?

You put resume in a finally block. Just like RequiresNew effectively does.

--
Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat


_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
Reply | Threaded
Open this post in threaded view
|

Re: CMT Batch Puzzle (Was Re: [Transaction synchronization between threads])

James Perkins
In reply to this post by jtgreene

On 02/04/2014 01:31 PM, Jason Greene wrote:

> On Feb 4, 2014, at 1:42 PM, James R. Perkins <[hidden email]> wrote:
>
>> I don't see in the spec where it requires any kind of transaction around a job repository. In fact the spec states "Note the implementation of the job repository is outside the scope of this specification.".
>>
>> The RI does have a JDBC repository, but it doesn't insert anything into the tables in a transaction.
>>
>> If we're only seeing this in PostgreSQL and a workaround with putting JobOperator.start() outside a transaction works, I would suggest that's okay for now. I do agree it needs to be fixed, but we might want to look at how we're handling transaction in JBeret as a whole. The RI, not that I want to model anything after it, uses it's own TransactionManagerAdapter. It might make sense for JBeret to use a TransactionManager rather than a UserTransaction. Or put the ownness on the SPI implementation of the BatchEnvironment to handle the transactions.
> Good points; and this brings me to my pathological batch puzzle. What does this code do:
>
> // Default gets transaction required
> String doStuff() {
>      long execID = jobOperator.start("simplejob", props);
>      BatchStatus status = jobOperator.getJobExecution(execID).getBatchStatus()
>      while (status != COMMITTED && status != FAILED && status != ABANDONED) {
>          Thread.sleep(1000);
>      }
>      return status.toString();
> }
Cheng will probably be better at answering as I'm still learning the
spec better, but in general it will depend on what's defined in your
simplejob.xml. For a JDBC repository it will perform an DB operations in
a UserTransaction retrieved from the
org.jboss.as.txn.service.TxnServices. This is the same UT that would be
used for any transactions required in the batch job as well.

For a in-memory repository, not transaction is used when updating the
repository.

Now what really happens with that code though is if it reaches one of
those states fast enough you'll have an endless loop :P
>
> --
> Jason T. Greene
> WildFly Lead / JBoss EAP Platform Architect
> JBoss, a division of Red Hat
>

--
James R. Perkins
Red Hat JBoss Middleware

_______________________________________________
wildfly-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/wildfly-dev
12