LoginSignup
0
0

More than 1 year has passed since last update.

SQLAlchemyにおけるcommitの誤用によるACID特性の破綻例

Last updated at Posted at 2022-07-03

概要

誤ったcommitの使用はトランザクションのACID特性を破綻させます。
ここでは実際に誤ったcommitの使い方によるACID特性の破綻を見ていきます。

トランザクションのACID特性が破綻する例

commit -> rollback -> commit
という動作を行いDBの内容がどうなるのか見ていきましょう。

commit -> rollback -> commit
engine = create_engine("mysql://user:password@db/test_db")
SessionClass = sessionmaker(engine, autoflush=False, autocommit=False)
session = SessionClass()

# commitで更新内容を確定
user = User(user_id="1", name="Johndoe", email="johndoe@example.com")
session.add(user)
session.commit()

# rollbackで更新内容を戻す
session.rollback()

# 再度commitで更新内容を確定
user = User(user_id="1", name="Johndoe", email="johndoe@example.com")
session.add(user)
session.commit()

上記のコードを実行すると以下のようなクエリが実行されます。

INSERT INTO user (id, name, email) VALUES ('1', 'Johndoe', 'johndoe@example.com')
COMMIT
ROLLBACK
INSERT INTO user (id, name, email) VALUES ('1', 'Johndoe', 'johndoe@example.com')
ROLLBACK

末尾のROLLBACKは直前のINSERTが失敗したことに対しての後処理としてシステムから呼ばれています。

また、pythonの実行ターミナルでは以下のエラーが発生します。

sqlalchemy.exc.IntegrityError: (MySQLdb.IntegrityError) (1062, "Duplicate entry '1' for key 'user.PRIMARY'")

1回目のcommitによりrollback不可な更新内容の確定が行われたため、
Primaryキーが同値のレコードをinsertするとエラーが発生します。


念の為にデータ更新ごとにcommitを行うという設計を行うと、
rollbackが出来なくなりACID特性を破綻させるという結果を招いてしまいます。

commitの使い方に関しては下記リンクを参照してみてください
SQLAlchemy flushとcommitの使い方

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0