8

それらの間の接続を閉じずに、複数のトランザクションに対して単一の MySQLdb 接続を使用しても問題ありませんか? つまり、次のようなものです。

conn = MySQLdb.connect(host="1.2.3.4", port=1234, user="root", passwd="x", db="test")

for i in range(10):
    try:
        cur = conn.cursor()
        query = "DELETE FROM SomeTable WHERE ID = %d" % i
        cur.execute(query)
        cur.close()
        conn.commit()

    except Exception:
        conn.rollback()

conn.close()

うまくいっているように見えますが、再確認したかっただけです。

4

2 に答える 2

20

ここで取引を構成するものについて誤解があると思います。

この例では、1 つの接続を開き、その上で1 つのトランザクションを実行します。そのトランザクションで複数の SQL ステートメントを実行しますが、コミット後に完全に閉じます。もちろん、それはそれで結構です。

(SQL ステートメントだけではなく)複数のトランザクションを実行すると、次のようになります。

conn = MySQLdb.connect(host="1.2.3.4", port=1234, user="root", passwd="x", db="test")

for j in range(10):
    try:
        for i in range(10):
            cur = conn.cursor()
            query = "DELETE FROM SomeTable WHERE ID = %d" % i
            cur.execute(query)
            cur.close()
        conn.commit()
    except Exception:
        conn.rollback()

conn.close()

上記のコードは、それぞれが 10 個の個別の削除ステートメントで構成される 10 個のトランザクションをコミットします。

はい、スレッド間でその接続を共有しない限り、開いている接続を問題なく再利用できるはずです。

たとえば、SQLAlchemyは接続をプールして再利用し、必要に応じて開いている接続をアプリケーションに渡します。新しいトランザクションと新しいステートメントは、アプリケーションがシャットダウンされるまで閉じる必要なく、アプリケーションの有効期間を通じてこれらの接続で実行されます。

于 2012-09-11T22:52:43.803 に答える
0

最初にクエリ文字列を作成してから、その 1 つの MySQL ステートメントを実行することをお勧めします。例えば:

query = "DELETE FROM table_name WHERE id IN ("
for i in range(10):
    query = query + "'" + str(i) + "', "
query = query[:-2] + ')'

cur = conn.cursor()
cur.execute(query)
于 2012-09-11T23:56:00.477 に答える