Search code examples
c#mysqltransactionsservicestackormlite-servicestack

ServiceStack Ormlite transaction read after commit returns null sometimes


We've run into a weird problem during automated testing. Sometimes we get a null return on a read after a commit, even though the data is commit as it should to the database.

code:

Repository.TransactionBegin();
        try
        {
            //Saves the HemUser
            Repository.SaveWithReferences(partyUserDb);
            // Save hpc-party relation with artifact
            Repository.SaveWithCredentials(hpcUserContext.ConvertTo<EconomyPartyRelationship>());
            Repository.SaveWithCredentials(hpcUserContext.ConvertTo<EconomyPartyRelHpcUser>());

            serviceCenterContexts.ForEach(a =>
            {
                Repository.SaveWithCredentials(a.ConvertTo<EconomyPartyRelationship>());
                Repository.SaveWithCredentials(a.ConvertTo<EconomyPartyRelServiceCenterUser>());
            });

            Repository.TransactionCommit();
            Console.WriteLine("leaving commit");
        }
        catch(Exception ex)
        {
            Repository.TransactionRollback();
            throw new HttpError(
                HttpStatusCode.PreconditionFailed,
                HemErrorCodes.FAILED_TO_CREATE_HEMUSER.ToString(),
                "Error creating HemUser. Ex: {0}".FormatWith(ex.Message));
        }
        Console.WriteLine(partyUserDb.Id);
        return FindUsersHelper.GetHpcContextUserById(dto.contextHpcId, partyUserDb.Id);

The FindUsersHelper.GetHpcContextUserById sometimes returns null even though the data is commited and exist in the database. If we do a wait it will work, but since it should be all sequential it shouldn't be able to return null if the commit was successfull.

The repository code for Repository.TransactionBegin() and Repository.TransactionCommit only handle start and stop for transactions if nesting is needed, but this is only one block and have no nested transaction statements.

We have tried running it in an explicit transaction without repository handling with the same result. We have run a profiler on the database and we see the commit being done before the select statements, but still sometimes it returns null. If we set a breakpoint(the same as wait really) it will work when we step over it.

30 - 50% of the calls fail.

Any ideas out there?

/Erik


Solution

  • We found the answer to this one. It was a datetime precision problem. Mysql rounds up the seconds no matter how small time part past a second it is, unless you define your precision. So a 2015-0828T22:02:34.1234 will be rounded up to 2015-0828T22:02:35 and that's an eternity for a validation datestamp.

    /Erik