MS SQL - Violation of PRIMARY KEY constraint

Categorii: Programare, Windows

14-Oct-2017 13:23 - 381 vizionari

Pentru o aplicatie de cantarire am facut cateva teste de utilizare a programului, o simulare de peste 7,000 de retete pe zi, timp de cateva zile.

Dupa o vreme, uneori dupa cateva ore de utilizare, alteori dupa cateva zile, obtin o eroare la introducerea datelor in SQL:

14-Oct-2017 12:17 - Task #0 retry 0 create cantariri (pymssql.IntegrityError) (2627, "Violation of PRIMARY KEY constraint 'PK__Cantarir__3213E83FDC5B857F'. Cannot insert duplicate key in object 'dbo.Cantariri'. The duplicate key value is (1041876).DB-Lib error message 20018, severity 14:\nGeneral SQL Server error: Check messages from the SQL Server\n") [SQL: 'INSERT INTO [Cantariri] (dataora, id_sarja, id_ingredient, valoare, dozarevalida) OUTPUT inserted.id VALUES (%(dataora)s, %(id_sarja)s, %(id_ingredient)s, %(valoare)s, %(dozarevalida)s)'] [parameters: {'dozarevalida': 1, 'valoare': 991.0, 'id_ingredient': 3, 'dataora': datetime.datetime(2017, 10, 14, 12, 17, 18, 886000), 'id_sarja': 365234}]

 

Cred ca este o consecinta a utilizarii parametrului -T272 la pornirea serverului SQL, ca sa rezolve o problema mentionata de mine mai de mult.

Ca sa ocolesc problema fara sa pierd date, in program am inserat o secventa de reluare de cateva ori (SQL_RETRY) a tranzactiei SQL, pana se termina cu succes sau se epuizeaza numarul de incercari. In caz de eroare, tranzactia este abandonata (rollback):


    ...
    ...
    ...
    for i in range(SQL_RETRY):
        try:
            cantarire = Cantariri()
            cantarire.dataora = datetime.datetime.now()
            cantarire.id_sarja = sarja.id
            cantarire.id_ingredient = id_ingredient
            cantarire.id_operator = operator.id
            cantarire.valoare = greutate_dozare
            if abs(cantarire.valoare - cantitate) <= toleranta:
                cantarire.dozarevalida = 1
            else:
                cantarire.dozarevalida = 0
                if isvqm:
                    flag_vqm_valid = False
            session.add(cantarire)
            session.commit()
            greutate_sac += cantarire.valoare
            greutate_dozare = 0
            confirmare_target = False
            break
        except Exception as ex:
            self.log('Task #{} retry {} create cantariri\n{}'.format(ix, i, str(ex)))
            session.rollback()
            time.sleep(0.5)
        #aici trebuie sa scriu in log ca tranzactia SQL a esuat de SQL_RETRY ori
    ...
    ...
    ...


In testele mele niciodata nu au fost doua erori SQL de integritate consecutive (s-ar fi vazut in log-uri numarul de incercari esuate), intotdeauna la a doua incercare datele au fost memorate cu succes.



Ultimele pagini: RSS

Alte adrese de Internet

Categorii

Istoric



Contorizari incepand cu 9 iunie 2014:
Flag Counter

Atentie: Continutul acestui server reprezinta ideile mele si acestea pot fi gresite.