0

データベースに複数の挿入を試みていますが、すべての挿入が正常に完了しない限りロールバックが発生します。次のようにブロック全体をラップすることで、TSQL でこれを簡単に行うことができます。

BEGIN TRANSACTION
BEGIN TRY
    --INSERTIONS GO HERE
    COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION;
    SELECT Error = 1
END CATCH

PYMSSQL を使用して Python でこの動作を再現しようとすると、次のようになります。

sql=""" SOME SQL CODE HERE """

try:
    cursor = DB.execute(sql)
except:
    DB.rollback()
    print('Fail')
    return False

sql=""" SOME DIFFERENT SQL CODE HERE """

try:
    cursor = DB.execute(sql)
except:
    DB.rollback()
    print('Fail')
    return False

DB.commit()
print('Success')
return True

これにより、トランザクションがコミットされず、DB に変更が見られません。また、この同じ方法を使用して 1 回挿入した後にコミットしようとすると、挿入は DB で行われますが、いくつかの複雑な親子の依存関係のために、タスクではすべての挿入が行われるか、まったく行われない必要があります。

また、永続的な DB 接続はシングルトンを使用して開かれていることにも言及する必要があります。これは、通常の接続方法を単純にオーバーライドしますが、単一の接続のみを次の方法で開くことができます。

def __init__(self, connid='one'):
     self.ensure_conn(connid)

 def ensure_conn(self, connid='one'):
     conn = getattr(self.connection_stack, connid, None)
     if conn is None:
         conn = pymssql.connect(
             self.server, self.user, self.password, self.database)
         self.connection_stack[connid] = conn

 def conn(self, connid='one'):
     self.ensure_conn(connid)
     if connid in self.connection_stack:
         return self.connection_stack[connid]
     else:
         return None

私はこのオンラインの例を見つけようとしましたが、問題はやや独特であるように思われるので、ご意見やご提案をいただければ幸いです。

4

1 に答える 1

0

私が見つけた解決策は、TSQL のストアド プロシージャを活用し、pymssql の rpc 機能を使用することでした。これには、SQL アカウント レベルでの EXEC 権限が必要ですが、安全上の理由から、ストアド プロシージャの設定に限定できます。

これを行うことで、異なるテーブルでの複数挿入のトランザクション動作を活用できます。

cursor.callproc(name, args)
于 2014-10-07T20:15:04.440 に答える