Ask a questionAsk a question
 

AnswerAdvise on creating Oracle Persistence

  • Monday, November 20, 2006 6:59 PMmickdelaney Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi Everyone,

    I've started to attempt an oracle persistence service as i've no choice on database. I've taken the schema scripts from the sql server persistence and mapped them into a set of oracle tables. Now its the stored procs.

    For now i'm not wrrying about locking or anything like that but am looking purely at getting the data in.

    The signature for the sql server sp is:

    Create Procedure [dbo].[InsertInstanceState]

    @uidInstanceID uniqueidentifier,

    @state image,

    @status int,

    @unlocked int,

    @blocked int,

    @info ntext,

    @ownerID uniqueidentifier = NULL,

    @ownedUntil datetime = NULL,

    @nextTimer datetime,

    @result int output,

    @currentOwnerID uniqueidentifier output

    What i'm trying to sort out is how to get the various values from the Activity passed into the

    SaveWorkflowInstanceState method i need to override in my custom service.

    i'm currently:

    storedProcedureExecutor["p_uidInstanceID "] = rootActivity.GetValue(Activity.ActivityContextGuidProperty);

    storedProcedureExecutor["p_State"] = GetDefaultSerializedForm(rootActivity);

    storedProcedureExecutor["p_Status"] = GetWorkflowStatus(rootActivity);

    storedProcedureExecutor["p_Blocked"] = GetIsBlocked(rootActivity);

    storedProcedureExecutor["p_Info"] = GetSuspendOrTerminateInfo(rootActivity);.

     

    What i was wondering is whether this is the right approach, i.e trying to replicate the sql server implementation. The only sample i can find at the moment is the File one which just dumps out a binary.. I'm trying to find values such as OwnedUntil, OwnerId etc...

    Is there any good docs on the sql server one??

    Regards...

     

Answers

  • Tuesday, November 21, 2006 1:02 AMPaul AndrewMSFTUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Hi Mick,

    Great project. Are you planning to share the resulting persistence with the community?

    I'd recommend you start with the file persistence service as a working implementation. And reimplement the functions step by step until you have the result you want.

    And let us know when you have some specific problems that we might be able to help with.

    Regards,
    Paul

All Replies

  • Monday, November 20, 2006 8:03 PMmickdelaney Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    it seems i needed a bit of config and some calculations. again if anyone can give me some pointers it'd be much appreciated. doesnt look like it going to be very trivial..

     

    public sealed class OracleWorkflowPersistenceService : WorkflowPersistenceService

    {

    private TimeSpan ownershipDelta;

    private Guid serviceInstanceId;

    public Guid ServiceInstanceId

    {

    get { return serviceInstanceId; }

    set { serviceInstanceId = value; }

    }

    public DateTime OwnershipTimeout

    {

    get

    {

    if (ownershipDelta == TimeSpan.MaxValue)

    {

    return DateTime.MaxValue;

    }

    return (DateTime.UtcNow + ownershipDelta);

    }

    }

    private bool enableRetries;

    public bool EnableRetries

    {

    get { return enableRetries; }

    set { enableRetries = value; }

    }

    private TimeSpan loadingInterval;

    public TimeSpan LoadingInterval

    {

    get { return loadingInterval; }

    set { loadingInterval = value; }

    }

    public OracleWorkflowPersistenceService() : base()

    {

    serviceInstanceId = Guid.Empty;

    //can Load From config

    ownershipDelta = TimeSpan.MaxValue;

    }

    public OracleWorkflowPersistenceService(NameValueCollection parameters)

    : base()

    {

    serviceInstanceId = Guid.Empty;

    //can Load From config

    ownershipDelta = TimeSpan.MaxValue;

    }

     

    ///<summary>

    ///Saves the workflow instance state to a data store.

    ///</summary>

    ///

    ///<param name="rootActivity">The root activity of the workflow instance.</param>

    ///<param name="unlock">true if the workflow instance should not be locked; false if the workflow instance should be locked.</param>

    protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock)

    {

    GenericSPExecutor executor = new GenericSPExecutor("WORKFLOWFOUNDATION_PKG.InsertInstanceState");

    executor["p_InstanceId"] = WorkflowEnvironment.WorkflowInstanceId;

    //Not sure what this is used for yet..

    Guid stateId = (Guid)rootActivity.GetValue(Activity.ActivityContextGuidProperty);

    WorkflowStatus status = GetWorkflowStatus(rootActivity);

    if ((status != WorkflowStatus.Completed) && (status != WorkflowStatus.Terminated))

    {

    executor["p_State"] = GetDefaultSerializedForm(rootActivity);

    }

    else

    {

    executor["p_State"] = new byte[0];

    }

    executor["p_Status"] = status;

    executor["p_Unlocked"] = unlock;

    executor["p_Blocked"] = GetIsBlocked(rootActivity);

    executor["p_Info"] = GetSuspendOrTerminateInfo(rootActivity);

    if (executor["p_Info"] == null)

    {

    executor["p_Info"] = "";

    }

    //ServiceInstanceId

    executor["p_OwnerId"] = ServiceInstanceId;

    //Config OwnerShip Timeout.

    if (OwnershipTimeout == DateTime.MaxValue)

    {

    executor["p_OwnedUntil"] = OracleDate.MaxValue;

    }

    else

    {

    executor["p_OwnedUntil"] = OwnershipTimeout;

    }

    TimerEventSubscription subscription1 = ((TimerEventSubscriptionCollection)rootActivity.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty)).Peek();

    executor["p_NextTimer"] = (subscription1 == null) ? DateTime.MaxValue : subscription1.ExpiresAt;

    executor.ExecuteNonQuery();

    CheckOwnershipResult(executor);

    }

    private void CheckOwnershipResult(GenericSPExecutor executor)

    {

    int result = Int32.Parse(executor["p_Result"].ToString());

    if (result == -2)

    {

    Guid currentOwnerId = (Guid)executor["p_CurrentOwnerId"];

    if (currentOwnerId == null)

    throw new WorkflowOwnershipException(WorkflowEnvironment.WorkflowInstanceId);

    }

    }

  • Tuesday, November 21, 2006 1:02 AMPaul AndrewMSFTUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Hi Mick,

    Great project. Are you planning to share the resulting persistence with the community?

    I'd recommend you start with the file persistence service as a working implementation. And reimplement the functions step by step until you have the result you want.

    And let us know when you have some specific problems that we might be able to help with.

    Regards,
    Paul

  • Tuesday, November 21, 2006 10:24 AMmickdelaney Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Thanks Paul.

    Definitely going to  share it. We've choosen WF and sharepoint going forward but have a large investment in oracle so this is quite a crucial area to get right.

    Regards.

  • Thursday, November 30, 2006 6:27 PMLarryRichardson Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    *** To the above comment: OH Please release this to the community!

    Larry

  • Tuesday, December 12, 2006 6:16 AMsbsgenius Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi mickdelaney

    I have the some problem of you. Have you solve this problem? If you do. Please give me a hand, My mail address:sbsgenius@gmail.com. Waiting the message from you. Thank you!

  • Friday, December 15, 2006 4:05 PMmickdelaney Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    hi guys,

    i had initially intended to release it start away but i've had some issues with the ip policy at work so i'm having to deal with that now. its working for now but has some issues that i'm hoping to iron out. hopefully i can rework it over the weekend to avoid these ip issues.

    cheers.

  • Friday, December 15, 2006 5:57 PMLarryRichardson Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    If there is any part of this that could use some assistance/coding, please let me know. I have *some* time and a need for a Oracle WF provider as well.
  • Saturday, December 16, 2006 11:39 AMmickdelaney Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi Larry,

    I''m going to post it by tommorow night (hopefully). At the moment it's written using ent lib 2 wrappers i developed for my company so i need to remove that from it becuase of the ip issues. once thats sorted i'll post the sql ddl &dml & the .net  classes. as i said it's not 100% yet though there are a few bugs. i used reflector to examine ms's sql server impl to get the basis of it, but i think if a few of us get together on it we'll sort it out in a couple of days. i've been having debugger and designer issues too (which i posted about!!!) which is really slowing everything down at the moment so bare with me. 

  • Sunday, December 17, 2006 4:50 PMmickdelaney Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    hi,

    i've created a rough oracle workflow persistence service...

    its on my blog. let me stress though that its not been thoroughly tested and just a quick stab.. i got most of the code from reflecting on the sql server impl...

    there's also a windows forms & state machine test harness...

    http://micksdevblog.blogspot.com/

    i'm hoping to get a few people to collaborate on this so we can finish it off...

    cheers..

  • Wednesday, February 07, 2007 7:20 PMbuiltsoftware Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi Mick. I would like to see your Oracle persistence work, but the download file is in RAR. Do you have it in a common format like zip or cab?

    Thanks,

    Matt
  • Thursday, February 08, 2007 10:52 AMvishblue Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    This is too good mick...and this is what I've been looking for...even I have Oracle DB as a constraint...

  • Monday, February 19, 2007 9:45 PMmickdelaney Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    i've actually found some bugs etc, so i need to update the code, when i do, i'll zip it instead. prob tommorow night. i'll update this when i do so.

    (sorry for the delay btw, was away for a while).

    cheers.

  • Friday, April 27, 2007 7:43 PMRS_babu Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    This is great. I am unable to download the files though. Can you please post it in the zip format ?

     

    Thank you

    RS

  • Monday, April 30, 2007 1:47 PMRS_babu Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi

    I am unable to get the source files for Oracle Persisstence service for Workflow. Can you please post the zip format ?

     

    thank you!

    RS

  • Wednesday, May 02, 2007 3:00 PMPjV Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hello world,

     

    Has anybody made an oracle persistence service that they can share with the community?

     

     

    Thanks,

     

    Peter

  • Wednesday, May 23, 2007 8:41 AMkepar Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

     

    hi Mick, first off thank u for this great initiative, I've wouldn't have known where to start otherwise!

     

    I think I found some kind of "bug" in the oracle package.

    My WFs didn't get loaded after the expiration of the timers so I did some debugging and

    found out that p_ownerID  wasn't getting used in GetExpiredTimerIds.

    So I believe this was what u intended to do:

     

    Code Snippet

     

    Procedure GetExpiredTimerIds
    (
      p_ownerID in wf_InstanceState.ownerID%type := null,
      p_ownedUntil in wf_InstanceState.ownedUntil%type := null,
      p_now in date,
      p_out out RefCursor
    )
    as
    begin
         
          open    p_out for    
          select  InstanceID
          from    wf_InstanceState
          where   nextTimer < p_now
          and     status != 1
          and     status != 3
          and     status != 2 -- not blocked and not completed and not terminated and not suspended
          and    
          (
            (unlocked = 1 and ownerID is null)
            or ownedUntil < sysdate
            or ownerID = p_ownerID -- if it's expired and I'm the owner then I should get it!?
          );
     
    end GetExpiredTimerIds;

     

     

     

    correct me if I'm wrong!

     

    Thanks again,

     

    kepar

  • Thursday, June 07, 2007 9:28 AMmickdelaney Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    hi guys,

    we've created a codeplex project called WFTools (workflow tools). at present there is a working oracle persistence provider. It uses the ms oracle provider,  not odp.net (which has a bug around transactionscope which we're currently trying to escelate with oracle.

    the long term desire is to add oracle providers for all other aspects of workflow, i.e. tracking etc... new contributers, testers etc would really help us to make this possible.

     

    so please come have a play download, test and contribute...

     

    http://www.codeplex.com/WFTools   

     

    regards,

    mick...

     

  • Thursday, June 07, 2007 12:40 PMDean Ward Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi kepar,

     

    Looks like you're using a very old version of the original Oracle persistence service. I'd advise you to visit http://www.codeplex.com/WFTools which has the latest version.

     

    v0.2 Alpha is the current release and works out of the box under XP/2003 with the MS Oracle Provider. There are some issues with the ODP.NET provider at present, we're escalating to Oracle

     

    Cheers,

     

    Dean Ward

    Project Co-ordinator

    WFTools