تراکنش های پایگاه داده¶

  • 2021-08-26

جنگو چند راه برای کنترل نحوه مدیریت تراکنش های پایگاه داده به شما ارائه می دهد.

مدیریت تراکنش های پایگاه داده¶

رفتار تراکنش پیش‌فرض جنگو

رفتار پیش‌فرض جنگو این است که در حالت خودکار اجرا شود. هر پرس و جو بلافاصله به پایگاه داده متعهد می شود، مگر اینکه تراکنش فعال باشد. برای جزئیات به زیر مراجعه کنید.

جنگو از تراکنش ها یا نقاط ذخیره به طور خودکار استفاده می کند تا یکپارچگی عملیات ORM را که به پرس و جوهای متعدد نیاز دارند، به ویژه پرس و جوهای delete() و update() تضمین کند.

کلاس TestCase جنگو نیز به دلایل عملکرد، هر آزمایش را در یک تراکنش می‌پیچد.

گره زدن تراکنش ها به درخواست های HTTP¶

یک راه متداول برای رسیدگی به تراکنش ها در وب، قرار دادن هر درخواست در یک تراکنش است. در پیکربندی هر پایگاه داده ای که می خواهید این رفتار را برای آنها فعال کنید، ATOMIC_REQUESTS را روی True تنظیم کنید.

اینجوری کار میکنهقبل از فراخوانی یک تابع view، جنگو یک تراکنش را شروع می کند. اگر پاسخ بدون مشکل تولید شود، جنگو تراکنش را انجام می دهد. اگر نمای یک استثنا ایجاد کند، جنگو تراکنش را به عقب برمی گرداند.

شما می توانید با استفاده از نقاط ذخیره در کد view خود، تراکنش های فرعی را انجام دهید، معمولاً با ()tomic manager context. با این حال، در پایان دیدگاه، یا تمام یا هیچ یک از تغییرات متعهد نخواهد بود.

در حالی که سادگی این مدل تراکنش جذاب است، اما در هنگام افزایش ترافیک آن را ناکارآمد می کند. باز کردن تراکنش برای هر نما مقداری سربار دارد. تأثیر بر عملکرد به الگوهای پرس و جو برنامه شما و اینکه پایگاه داده شما چگونه قفل را مدیریت می کند بستگی دارد.

تراکنش های هر درخواست و پاسخ های جریانی

وقتی یک view یک StreamingHttpResponse را برمی‌گرداند، خواندن محتوای پاسخ اغلب کدی را برای تولید محتوا اجرا می‌کند. از آنجایی که نمای قبلاً بازگشته است، چنین کدی خارج از تراکنش اجرا می شود.

به طور کلی، نوشتن در پایگاه داده هنگام ایجاد پاسخ جریانی توصیه نمی شود، زیرا هیچ راه معقولی برای رسیدگی به خطاها پس از شروع ارسال پاسخ وجود ندارد.

در عمل، این ویژگی هر تابع view را در دکوراتور atomic() که در زیر توضیح داده شده است می‌پیچد.

توجه داشته باشید که فقط اجرای نمای شما در تراکنش ها محصور شده است. میان‌افزار خارج از تراکنش اجرا می‌شود، و همچنین رندر پاسخ‌های الگو نیز اجرا می‌شود.

وقتی ATOMIC_REQUESTS فعال است، همچنان می‌توان از اجرای نماها در یک تراکنش جلوگیری کرد.

non_atomic_requests ( با استفاده از = هیچ ) [منبع] ¶

این دکوراتور تأثیر ATOMIC_REQUESTS را برای یک نمای معین نفی می کند:

فقط در صورتی کار می کند که روی خود نما اعمال شود.

کنترل صریح تراکنش ها

جنگو یک API واحد برای کنترل تراکنش های پایگاه داده ارائه می دهد.

اتمی (استفاده از = هیچ، savepoint = درست، بادوام = نادرست) [منبع] ¶

اتمی بودن ویژگی تعیین کننده تراکنش های پایگاه داده است. atomic به ما اجازه می دهد تا یک بلوک از کد ایجاد کنیم که در آن اتمی بودن پایگاه داده تضمین شده است. اگر بلوک کد با موفقیت تکمیل شود، تغییرات به پایگاه داده متعهد می شوند. اگر استثنا وجود داشته باشد، تغییرات برگردانده می شوند.

بلوک های اتمی را می توان تودرتو کرد. در این مورد، زمانی که یک بلوک داخلی با موفقیت کامل می‌شود، اگر در مرحله‌ای بعد در بلوک بیرونی یک استثنا مطرح شود، اثرات آن همچنان قابل برگشت است.

گاهی اوقات برای اطمینان از بلوک اتمی همیشه بیرونی ترین بلوک اتمی مفید است ، و اطمینان حاصل می شود که در هنگام خروج از بلوک بدون خطا ، هرگونه تغییر پایگاه داده انجام می شود. این به دوام معروف است و با تنظیم دوام = درست می توان به دست آورد. اگر بلوک اتمی در داخل دیگری قرار بگیرد ، یک ریچر را افزایش می دهد.

اتمی هم به عنوان دکوراتور قابل استفاده است:

بسته بندی اتمی در یک آزمایش/به جز بلوک امکان رسیدگی به طبیعی خطاهای یکپارچگی را فراهم می کند:

در این مثال ، حتی اگر GEMETER_RELATIONS () با شکستن یک محدودیت یکپارچگی باعث ایجاد خطای پایگاه داده شود ، می توانید نمایش داده ها را در add_children () اجرا کنید ، و تغییرات از Creat_Parent () هنوز وجود دارد و به همان معامله محدود می شود. توجه داشته باشید که هر عملیاتی که در Generate_Relations () انجام شود ، در صورت فراخوانی Handle_Exception () با خیال راحت به عقب برگردانده می شود ، بنابراین کنترل کننده استثنا نیز در صورت لزوم می تواند در پایگاه داده فعالیت کند.

از گرفتن استثنائات در داخل اتمی خودداری کنید!

در هنگام خروج از بلوک اتمی ، جنگو به این موضوع می پردازد که آیا به طور عادی از آن خارج شده است یا به استثناء برای تعیین اینکه آیا مرتکب یا عقب نشینی می شود. اگر استثنائات را در داخل یک بلوک اتمی گرفتار کرده و به آن رسیدگی کنید ، ممکن است این واقعیت را از جنگو مخفی کنید. این می تواند منجر به رفتار غیر منتظره شود.

این بیشتر نگرانی برای DatabaseError و زیر کلاس های آن مانند IntecrityError است. پس از چنین خطایی ، معامله خراب است و Django در انتهای بلوک اتمی یک بازپرداخت انجام می دهد. اگر قبل از وقوع بازپرداخت سعی در اجرای نمایش داده های بانک اطلاعاتی داشته باشید ، Django یک TransactionManagementError را جمع می کند. همچنین ممکن است با این رفتار روبرو شوید که یک کنترل کننده سیگنال مربوط به ORM یک استثنا را مطرح می کند.

روش صحیح برای گرفتن خطاهای پایگاه داده در اطراف یک بلوک اتمی همانطور که در بالا نشان داده شده است. در صورت لزوم ، برای این منظور یک بلوک اتمی اضافی اضافه کنید. این الگوی یک مزیت دیگر دارد: صریحاً مشخص می کند که در صورت بروز یک استثنا ، کدام عملیات به عقب برگردانده می شود.

اگر استثنائات مطرح شده توسط نمایش داده های SQL RAW را بدست آورید ، رفتار Django نامشخص و وابسته به پایگاه داده است.

ممکن است لازم باشد هنگام بازگشت به معامله ، حالت را به صورت دستی برگردانید.

مقادیر زمینه های یک مدل هنگامی که یک بازپرداخت معامله اتفاق می افتد برگردانده نمی شوند. این می تواند به یک حالت مدل متناقض منجر شود ، مگر اینکه شما مقادیر اصلی زمینه را به صورت دستی بازیابی کنید.

به عنوان مثال ، با توجه به MyModel با یک زمینه فعال ، این قطعه تضمین می کند که اگر در پایان actact actact در پایان از مقدار صحیح استفاده می کند در صورت عدم موفقیت در True در معامله ، از مقدار صحیح استفاده می کند:

به منظور تضمین اتمی ، اتمی برخی از API ها را غیرفعال می کند. تلاش برای تعهد ، عقب نشینی یا تغییر وضعیت خودکار اتصال پایگاه داده در یک بلوک اتمی ، یک استثنا را افزایش می دهد.

Atomic یک آرگومان را می گیرد که باید نام یک پایگاه داده باشد. اگر این استدلال ارائه نشده باشد ، Django از پایگاه داده "پیش فرض" استفاده می کند.

در زیر کاپوت ، کد مدیریت معاملات Django:

  • هنگام ورود به بیرونی ترین بلوک اتمی ، معامله را باز می کند.
  • هنگام ورود به یک بلوک اتمی داخلی ، یک نقطه ذخیره ایجاد می کند.
  • هنگام خروج از یک بلوک داخلی ، آزاد می شود یا به SavePoint باز می گردد.
  • هنگام خروج از بیرونی ترین بلوک ، معامله را مرتکب یا بازگردانید.

با تنظیم استدلال SavePoint به False می توانید ایجاد SavePoints را برای بلوک های داخلی غیرفعال کنید. در صورت بروز یک استثنا ، در هنگام خروج از بلوک اول والدین با SavePoint در صورت وجود ، Django بازپرداخت را انجام می دهد و در غیر این صورت بیرونی ترین بلوک. اتمی هنوز توسط معامله بیرونی تضمین شده است. این گزینه فقط باید در صورتی مورد استفاده قرار گیرد که سربار SavePoints قابل توجه باشد. این اشکال در شکستن خطای رسیدگی در بالا است.

ممکن است هنگام خاموش شدن اتمی از اتمی استفاده کنید. این فقط از SavePoints ، حتی برای بیرونی ترین بلوک استفاده می کند.

معاملات باز هزینه عملکرد برای سرور پایگاه داده شما دارند. برای به حداقل رساندن این سربار ، معاملات خود را تا حد امکان کوتاه نگه دارید. این امر به ویژه در صورت استفاده از اتمی () در فرآیندهای طولانی مدت ، خارج از چرخه درخواست / پاسخ Django بسیار مهم است.

در نسخه های قدیمی ، بررسی دوام در django. test. testcase غیرفعال شد.

خودکار

چرا Django از AutoCommit¶ استفاده می کند

در استانداردهای SQL ، هر پرس و جو SQL معامله را شروع می کند ، مگر اینکه یکی از قبل فعال باشد. چنین معاملات باید صریحاً متعهد یا برگشت شوند.

این همیشه برای توسعه دهندگان برنامه مناسب نیست. برای کاهش این مشکل ، بیشتر بانکهای اطلاعاتی یک حالت خودکار را ارائه می دهند. هنگامی که AutoCommit روشن است و هیچ معامله ای فعال نیست ، هر پرس و جو SQL در معامله خود پیچیده می شود. به عبارت دیگر ، نه تنها هر یک از این پرس و جو ها معامله را آغاز می کنند ، بلکه بسته به اینکه آیا پرس و جو موفق شده است ، به طور خودکار متعهد یا به عقب می رود.

PEP 249 ، مشخصات API پایگاه داده Python v2. 0 ، نیاز به خاموش شدن اتوماسیون در ابتدا دارد. جنگو این پیش فرض را نادیده می گیرد و AutoCommit را روشن می کند.

برای جلوگیری از این امر ، می توانید مدیریت معامله را غیرفعال کنید ، اما توصیه نمی شود.

غیرفعال کردن مدیریت معاملات

شما می توانید مدیریت معاملات Django را برای یک پایگاه داده خاص با تنظیم AutomMitit در FALSE در پیکربندی آن کاملاً غیرفعال کنید. اگر این کار را انجام دهید ، Django AutoCommit را فعال نمی کند ، و هیچ تعهدی را انجام نمی دهد. رفتار منظم کتابخانه پایگاه داده زیرین را دریافت خواهید کرد.

این امر شما را ملزم به انجام صریح هر معامله ، حتی مواردی است که توسط Django یا کتابخانه های شخص ثالث آغاز شده است. بنابراین ، این به بهترین وجه در شرایطی که می خواهید میانی کنترل کننده معامله خود را اجرا کنید یا کاری واقعاً عجیب انجام دهید ، استفاده می شود.

انجام اقدامات پس از تعهد

بعضی اوقات شما نیاز به انجام یک اقدام مربوط به معامله پایگاه داده فعلی دارید ، اما فقط در صورت موفقیت معامله انجام می شود. مثالها ممکن است شامل یک کار کرفس ، یک اعلان ایمیل یا عدم اعتبار حافظه پنهان باشد.

Django عملکرد ON_COMMIT () را برای ثبت توابع پاسخ به تماس که باید پس از انجام معامله با موفقیت انجام شود ، ارائه می دهد:

عبور از هر عملکردی (که هیچ آرگومی ندارد) به on_commit ():

همچنین می توانید با استفاده از functools. partial () آرگومان ها را به عملکرد خود وصل کنید.

عملکردی که در آن عبور می کنید بلافاصله پس از نوشتن پایگاه داده فرضی که در آن on_commit () خوانده می شود ، با موفقیت انجام می شود.

اگر با on_commit () تماس بگیرید در حالی که یک معامله فعال وجود ندارد ، پاسخ به تماس بلافاصله انجام می شود.

اگر این پایگاه داده فرضی به جای آن به عقب برگردد (به طور معمول هنگامی که یک استثناء نامعلوم در یک بلوک اتمی () مطرح می شود) ، عملکرد شما دور ریخته می شود و هرگز فراخوانی نمی شود.

SavePoints¶

نقاط ذخیره (یعنی بلوک‌های اتمی تو در تو) به درستی مدیریت می‌شوند. یعنی یک on_commit () قابل فراخوانی که پس از یک savepoint (در یک بلوک atomic() تودرتو) پس از انجام تراکنش خارجی فراخوانی می‌شود، اما اگر در طول تراکنش، بازگشتی به آن savepoint یا هر ذخیره قبلی رخ داده باشد، چنین نیست:

از سوی دیگر، هنگامی که یک savepoint به عقب برگردانده می شود (به دلیل ایجاد یک استثنا)، قابلیت فراخوانی داخلی فراخوانی نمی شود:

دستور اجرا

توابع On-commit برای یک تراکنش معین به ترتیبی که ثبت شده اند اجرا می شوند.

رسیدگی به استثناء

اگر یک تابع on-commit در یک تراکنش معین، یک استثناء کشف نشده ایجاد کند، هیچ توابعی که بعداً ثبت شده در همان تراکنش اجرا نخواهد شد. این همان رفتاری است که اگر خودتان بدون ()on_commit توابع را به صورت متوالی اجرا کرده باشید.

زمان اجرا

تماس‌های شما پس از یک commit موفقیت‌آمیز اجرا می‌شوند، بنابراین شکست در یک callback باعث بازگشت تراکنش نمی‌شود. آنها مشروط به موفقیت معامله انجام می شوند، اما بخشی از معامله نیستند. برای موارد استفاده مورد نظر (اعلان های پستی، وظایف Celery و غیره)، این باید خوب باشد. اگر اینطور نیست (اگر اقدام پیگیری شما آنقدر حیاتی است که شکست آن باید به معنی شکست خود تراکنش باشد)، پس نمی‌خواهید از قلاب ()on_commit استفاده کنید. در عوض، ممکن است بخواهید commit دو فازی مانند پشتیبانی از پروتکل دو فازی psycopg و افزونه‌های دو فازی اختیاری در مشخصات DB-API پایتون را داشته باشید.

تماس‌های برگشتی اجرا نمی‌شوند تا زمانی که Autocommit بر روی اتصال پس از commit بازیابی شود (زیرا در غیر این صورت هر درخواستی که در یک callback انجام می‌شود یک تراکنش ضمنی را باز می‌کند و از بازگشت اتصال به حالت Autocommit جلوگیری می‌کند).

هنگامی که در حالت Autocommit و خارج از یک بلوک atomic() قرار دارید، این تابع بلافاصله اجرا می شود، نه در commit.

توابع On-commit فقط با حالت Autocommit و API تراکنش atomic() (یا ATOMIC_REQUESTS ) کار می کنند. فراخوانی on_commit () زمانی که autocommit غیرفعال است و شما در یک بلوک اتمی نیستید منجر به خطا می شود.

استفاده در تست ها

کلاس TestCase جنگو، هر تست را در یک تراکنش می‌پیچد و پس از هر تست، آن تراکنش را برمی‌گرداند تا جداسازی آزمایشی را ارائه دهد. این بدان معنی است که هیچ تراکنشی واقعاً انجام نمی شود، بنابراین فراخوان های on_commit () هرگز اجرا نمی شوند.

شما می توانید با استفاده از TestCase. captureOnCommitCallbacks() بر این محدودیت غلبه کنید. این فراخوانی ()on_commit شما را در یک لیست ثبت می‌کند و به شما امکان می‌دهد در مورد آن‌ها اظهارنظر کنید یا با فراخوانی آن‌ها، committing تراکنش را شبیه‌سازی کنید.

راه دیگر برای غلبه بر محدودیت استفاده از TransactionTestCase به جای TestCase است. این بدان معناست که تراکنش‌های شما متعهد شده‌اند و تماس‌های برگشتی اجرا می‌شوند. با این حال، TransactionTestCase پایگاه داده را بین تست ها شستشو می دهد، که به طور قابل توجهی کندتر از جداسازی TestCase است.

چرا قلاب برگشتی وجود ندارد؟¶

اجرای یک قلاب برگشتی سخت تر از یک قلاب commit است، زیرا موارد مختلفی می توانند باعث بازگشت ضمنی شوند.

به عنوان مثال، اگر اتصال پایگاه داده شما به دلیل قطع شدن فرآیند شما بدون فرصتی برای خاموش شدن به خوبی قطع شود، قلاب بازگشتی شما هرگز اجرا نخواهد شد.

اما یک راه حل وجود دارد: به جای انجام کاری در طول بلوک اتمی (تراکنش) و سپس لغو آن در صورت شکست تراکنش، از on_commit() استفاده کنید تا انجام آن را در وهله اول تا بعد از موفقیت تراکنش به تاخیر بیندازید. خنثی کردن کاری که از ابتدا انجام نداده اید بسیار آسان تر است!

API های سطح پایین¶

در صورت امکان همیشه atomic() را ترجیح دهید. این ویژگی های خاص هر پایگاه داده را در نظر می گیرد و از عملیات نامعتبر جلوگیری می کند.

API های سطح پایین تنها زمانی مفید هستند که مدیریت تراکنش خود را پیاده سازی کنید.

خودکار

Django یک API در ماژول django. db. transaction برای مدیریت وضعیت خودکار هر اتصال پایگاه داده ارائه می دهد.

get_autocommit ( با استفاده از = هیچ ) [منبع] ¶ set_autocommit ( Autocommit , using = None ) [منبع] ¶

این توابع یک آرگومان با استفاده را می گیرند که باید نام یک پایگاه داده باشد. اگر ارائه نشده باشد، جنگو از پایگاه داده «پیش‌فرض» استفاده می‌کند.

Autocommit در ابتدا روشن است. اگر آن را خاموش کنید، مسئولیت بازیابی آن بر عهده شماست.

هنگامی که Autocommit را خاموش کردید، رفتار پیش‌فرض آداپتور پایگاه داده خود را دریافت می‌کنید و جنگو به شما کمکی نمی‌کند. اگرچه این رفتار در PEP 249 مشخص شده است، پیاده سازی آداپتورها همیشه با یکدیگر سازگار نیستند. اسناد آداپتوری را که استفاده می کنید به دقت بررسی کنید.

باید مطمئن شوید که هیچ تراکنش فعال نیست، معمولاً با صدور یک commit() یا یک rollback() قبل از اینکه commit را مجدداً روشن کنید.

جنگو از خاموش کردن Autocommit زمانی که یک بلوک atomic() فعال است، امتناع می‌کند، زیرا این امر باعث شکسته شدن اتمی می‌شود.

معاملات¶

تراکنش مجموعه ای اتمی از پرس و جوهای پایگاه داده است. حتی اگر برنامه شما از کار بیفتد، پایگاه داده تضمین می کند که یا تمام تغییرات اعمال می شود یا هیچ یک از آنها اعمال نمی شود.

جنگو یک API برای شروع تراکنش ارائه نمی دهد. راه مورد انتظار برای شروع تراکنش غیرفعال کردن Autocommit با set_autocommit() است.

هنگامی که در یک تراکنش هستید، می‌توانید تغییراتی را که تا این مرحله انجام داده‌اید با commit() اعمال کنید یا با rollback() لغو کنید. این توابع در django. db. transaction تعریف شده اند.

commit ( با استفاده از = هیچ ) [منبع] ¶ بازگشت (استفاده از = هیچ ) [منبع] ¶

این توابع یک آرگومان با استفاده را می گیرند که باید نام یک پایگاه داده باشد. اگر ارائه نشده باشد، جنگو از پایگاه داده «پیش‌فرض» استفاده می‌کند.

هنگامی که یک بلوک atomic() فعال است، جنگو از commit یا عقب نشینی خودداری می کند، زیرا این امر باعث شکسته شدن اتمی می شود.

SavePoints¶

Savepoint یک نشانگر در یک تراکنش است که به شما امکان می دهد بخشی از تراکنش را به عقب برگردانید، نه تراکنش کامل. نقاط ذخیره با پشتیبان های SQLite، PostgreSQL، Oracle و MySQL (هنگام استفاده از موتور ذخیره سازی InnoDB) در دسترس هستند. سایر پشتیبان‌ها توابع ذخیره‌سازی را ارائه می‌کنند، اما آنها عملیات خالی هستند - آنها در واقع هیچ کاری انجام نمی‌دهند.

اگر از Autocommit، رفتار پیش‌فرض جنگو استفاده می‌کنید، نقاط ذخیره به‌خصوص مفید نیستند. با این حال، هنگامی که یک تراکنش را با () atomic باز می کنید، یک سری عملیات پایگاه داده را در انتظار commit یا rollback ایجاد می کنید. اگر بازگشتی صادر کنید، کل تراکنش برگشت داده می شود. نقاط ذخیره به جای بازگشت کامل که توسط ()transaction. rollback انجام می شود، توانایی انجام یک بازگشت ریز دانه را فراهم می کند.

هنگامی که دکوراتور ()atomic تو در تو است، یک Savepoint ایجاد می کند تا امکان commit یا بازگشت جزئی را فراهم کند. شما قویاً تشویق می‌شوید به جای توابع توضیح داده شده در زیر از atomic() استفاده کنید، اما آنها همچنان بخشی از API عمومی هستند و برنامه‌ای برای منسوخ کردن آنها وجود ندارد.

هر یک از این توابع یک آرگومان استفاده می‌گیرد که باید نام پایگاه داده‌ای باشد که رفتار برای آن اعمال می‌شود. اگر هیچ آرگومان استفاده ای ارائه نشده باشد، از پایگاه داده "پیش فرض" استفاده می شود.

نقاط ذخیره توسط سه تابع در django. db. transaction کنترل می شوند:

SavePoint جدید ایجاد می کند. این یک نکته در معامله است که شناخته شده است که در حالت "خوب" قرار دارد. شناسه SavePoint (SID) را برمی گرداند.

savePoint_commit (sid ، با استفاده از = هیچ) [منبع]

SavePoint SID را منتشر می کند. تغییرات انجام شده از زمان ایجاد SavePoint بخشی از معامله شد.

savePoint_rollback (sid ، با استفاده از = هیچ) [منبع]

معامله را به عقب برگردانید تا SavePoint SID را ذخیره کنید.

این توابع در صورت پشتیبانی از SavePoints یا اینکه پایگاه داده در حالت AutomMit است ، کاری انجام نمی دهند.

علاوه بر این ، یک عملکرد ابزار وجود دارد:

Clean_savePoints (با استفاده از = هیچ) [منبع]

پیشخوان مورد استفاده برای تولید شناسه های منحصر به فرد SavePoint را تنظیم می کند.

مثال زیر استفاده از SavePoints را نشان می دهد:

SavePoints ممکن است برای بازیابی از خطای پایگاه داده با انجام یک بازگشت جزئی استفاده شود. اگر این کار را در داخل یک بلوک اتمی () انجام می دهید ، کل بلوک هنوز به عقب برگردانده می شود ، زیرا نمی داند شما وضعیت را در سطح پایین تر اداره کرده اید!برای جلوگیری از این امر ، می توانید رفتار برگشت با عملکردهای زیر را کنترل کنید.

get_rollback (با استفاده از = هیچ) [منبع] ¶ set_rollback (بازگشت ، با استفاده از = هیچ) [منبع]

هنگام خروج از بلوک اتمی درونی ، پرچم برگشت را به صورت واقعی بازپرداخت می کند. این ممکن است برای ایجاد یک بازگشت بدون ایجاد یک استثنا مفید باشد.

تنظیم آن در False از چنین بازگشت مجدد جلوگیری می کند. قبل از انجام این کار ، اطمینان حاصل کنید که معامله را به یک نقطه ذخیره خوب شناخته شده در بلوک اتمی فعلی برگردانید!در غیر این صورت ممکن است اتمی و فساد داده را بشکنید.

یادداشت های خاص پایگاه داده ¶

SavePoints در SQLite¶

در حالی که SQLite از SavePoints پشتیبانی می کند ، نقصی در طراحی ماژول SQLite3 باعث می شود آنها به سختی قابل استفاده باشند.

هنگامی که AutoCommit فعال شد ، SavePoints معنی ندارد. هنگامی که غیرفعال است ، SQLite3 قبل از اظهارات SavePoint به طور ضمنی مرتکب می شود.(در واقع ، آن را قبل از هر جمله ای غیر از انتخاب ، درج ، به روزرسانی ، حذف و جایگزینی تعهد می کند.) این اشکال دارای دو پیام است:

  • API های سطح پایین برای SavePoints فقط در یک معامله یعنی داخل یک بلوک اتمی () قابل استفاده هستند.
  • استفاده از اتمی () هنگام خاموش شدن اتمی غیرممکن است.

معاملات در mysql¶

اگر از MySQL استفاده می کنید ، جداول شما ممکن است از معاملات پشتیبانی کند یا نباشد. این بستگی به نسخه MySQL شما و انواع جدول شما استفاده می کند.(با استفاده از "انواع جدول" ، منظور ما چیزی مانند "InnoDB" یا "MyIsam" است.) خصوصیات معاملات MySQL خارج از محدوده این مقاله است ، اما سایت MySQL اطلاعاتی در مورد معاملات MySQL دارد.

اگر تنظیم MySQL شما از معاملات پشتیبانی نمی کند ، Django همیشه در حالت AutomMitt عمل خواهد کرد: بیانیه ها به محض فراخوانی آنها اجرا و انجام می شود. اگر تنظیمات MySQL شما از معاملات پشتیبانی کند ، Django مطابق با این سند معاملات را انجام می دهد.

رسیدگی به استثنائات در معاملات postgreSQL

این بخش فقط در صورت اجرای مدیریت معاملات خود مرتبط است. این مشکل نمی تواند در حالت پیش فرض Django رخ دهد و اتمی () آن را به طور خودکار انجام می دهد.

در داخل یک معامله ، هنگامی که تماس با یک مکان نما PostgresQL یک استثناء (به طور معمول یکپارچگی) ایجاد می کند ، تمام SQL بعدی در همان معامله با خطا شکست می خورند "معامله فعلی سقط شده است ، نمایش داده شد تا پایان بلوک معامله نادیده گرفته می شود". در حالی که استفاده اصلی از Save () بعید است که یک استثناء در PostgreSQL ایجاد کند ، الگوهای استفاده پیشرفته تری وجود دارد که ممکن است مانند صرفه جویی در اشیاء با زمینه های منحصر به فرد ، صرفه جویی در استفاده از پرچم Force_Insert/Force_Update یا فراخوانی SQL سفارشی.

راه های مختلفی برای بازیابی از این نوع خطا وجود دارد.

بازگشت تراکنش¶

اولین گزینه این است که کل تراکنش را به عقب برگردانید. مثلا:

فراخوانی ()transaction. rollback کل تراکنش را به عقب برمی گرداند. هر گونه عملیات پایگاه داده غیرمتعهد از بین خواهد رفت. در این مثال، تغییرات ایجاد شده توسط a. save() از بین خواهند رفت، حتی اگر آن عملیات خود خطایی ایجاد نکرد.

بازگشت نقطه ذخیره¶

شما می توانید از نقاط ذخیره برای کنترل میزان بازگشت استفاده کنید. قبل از انجام یک عملیات پایگاه داده که ممکن است با شکست مواجه شود، می توانید نقطه ذخیره را تنظیم یا به روز کنید. به این ترتیب، اگر عملیات با شکست مواجه شد، می توانید به جای کل تراکنش، عملیات مجرمانه را به عقب برگردانید. مثلا:

در این مثال، a. save() در موردی که b. save() یک استثنا ایجاد کند، لغو نخواهد شد.

ثبت دیدگاه

مجموع دیدگاهها : 0در انتظار بررسی : 0انتشار یافته : ۰
قوانین ارسال دیدگاه
  • دیدگاه های ارسال شده توسط شما، پس از تایید توسط تیم مدیریت در وب منتشر خواهد شد.
  • پیام هایی که حاوی تهمت یا افترا باشد منتشر نخواهد شد.
  • پیام هایی که به غیر از زبان فارسی یا غیر مرتبط باشد منتشر نخواهد شد.