1
Vote

Transaction hangs SQLite

description

Hi all,

just tried to run few commands in transaction on SQLite, and it hangs. I`ve used this code:
 //Complex object named f was loaded 

using (var context = _dstore.StartTransaction())
{
       context.Instance.InsertObject(f); //hangs here
       context.Instance.InsertObject(f.Child);
       f.Child_id = f.Child.id;
       context.Instance.SaveObject(f);

       context.Commit();
}
If i try this commands without using transactions, it works fine.

Any help would be appreciated.

comments

iamkrillin wrote May 6, 2014 at 2:23 AM

instead of using context.Instance.SaveObject() use context.Instance.UpdateObject()

the difference is that UpdateObject will cause sauce to do a straight update command, however, using SaveObject() will cause sauce to do a lookup to see if the object exists in the store and then do an update or insert.

iamkrillin wrote May 6, 2014 at 2:28 AM

can you send me your class definition for f?

eyej wrote May 6, 2014 at 9:36 AM

Thanks for your quick response.

It hangs on the first line (InsertObject), even if i try UpdateObject method.

Sure, class definitions are:
public class Foo
    {
        public int id { get; set;}
        public string Name {get; set;}

        [DataField(PrimaryKeyType = typeof(FooChild), RelationshipType=ForeignKeyType.Cascade)]
        public int Child_id { get; set; }
        
        [IgnoredField]
        public FooChild Child { get; set; }

        [AdditionalInit]
        private void LoadChild(IDataStore dstore)
        {
            var child = dstore.LoadObject<FooChild>(Child_id);
            if (child != null) 
                Child = child; //Since i am using [Nancy binding mechanism](https://github.com/NancyFx/Nancy/wiki/Model-binding), i needed to write it this way so Bind method could load complex object for me when i get it from API call in this format {Name:"Parent",Child:{Name:"Child"}}
        }
    }

    public class FooChild
    {
        public int id { get; set; }
        public string Name { get; set; }

    }
I need a scenario with complex objects so this is how i tried to implement first. As said, without transactions, everything works fine. The problem starts on with transactions.

Anyway, since i was not sure whether i am doing things right with complex object definition, i also tried with simple object (just name), and it hangs as well.

If you need any additional info, please let me know.

Cheers

iamkrillin wrote May 6, 2014 at 12:24 PM

Thank you for posting your type definition. The problem you are having here is that the Type Foo has not been though the type validator yet and and thats causing sqlite to lock something during the transaction.

Add this line of code before your transaction block

dstore.TypeInformationParser.GetTypeInfo(typeof(Foo));

using (var context = dstore.StartTransaction())
{
//do work here
}

I'll think about how best to address this in an upcoming release so this step is not needed.

wrote May 6, 2014 at 12:24 PM

eyej wrote May 6, 2014 at 1:37 PM

Thanks, using type validator, it finally worked.

Other than that, is there any working guidelines or examples how to handle complex objects?

Anyway, thanks for help.

iamkrillin wrote May 6, 2014 at 2:28 PM

The advice I will give for now, just make sure that your types have ran though the validator prior to starting a transaction with those object types.

Things that cause a type to validate:
1) An update
2) An Insert
3) Any type of query **read pretty much any method that involves <T> or Type as an argument
4) Manually parsing the type as was done above

Outside of this edge case, no special thought needs to be given to complex objects.

iamkrillin wrote Dec 2, 2014 at 12:10 AM