Mysql Programming CS 155P笔记(六) Transactions

Transactions

A transaction is a set of statements all of which need to complete or none of which should complete. 

In many complex cases, it's impossible to do everything you need in a single SQL statement.

Lets look at a couple examples:

SHOPPING CART Checkout transaction:
In our shopping cart, when a customer wants to checkout and buy all the items in their cart, a series of things need to happen effectively all at the same time.  For simplicity sake, lets say that we aren't allowed to sell more inventory than we have (no backorders or online download [unlimited inventory]):

We've collected all the billing and shipping and payment info.  We now need to do the following:

  1. store the payment confirmation
  2. reduce the inventory of each item
  3. add the purchase to the users transaction history
  4. identify customers to the vendors for warranty information or customer notifications
  5. clear the users shopping cart

This is likely done via a series of SQL statements.. at least one per task, but some tasks may have multiple queries.  In any case, if any of these steps doesn't work (we ran out of inventory, for example), we don't want any of these queries to actually change database info (we certainly shouldn't clear the cart--although we may want to remove the out of inventory item or mark it as unavailable in the users cart), we don't want to add this to the transaction history, we shouldn't reduce inventory of other items since we aren't completing this transaction, and we should reverse the payment transaction (ideally this is done via a hold which is lifted rather than a purchase that is reversed, but that's out of scope for this class).

Without transactions, out software would have to keep track of all the queries executed and when it ran into a problem, we'd have to run queries to undo all the work we just did.

In the transactions world, we can simply roll back the transaction and all pending DB changes would be undone.    Similarly, if we're happy and everything is fine, we can commit the changes and all tables will be updated effectively simultaneously.

Transaction commit and rollback can be included in procedures/functions as well.

Here's an example:

DELIMITER $$

CREATE PROCEDURE `sp_fail`()
BEGIN
    DECLARE `_rollback` BOOL DEFAULT 0;
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET `_rollback` = 1;
    START TRANSACTION;
    INSERT INTO `tablea` (`date`) VALUES (NOW());
    INSERT INTO `tableb` (`date`) VALUES (NOW());
    INSERT INTO `tablec` (`date`) VALUES (NOW()); -- FAIL
    IF `_rollback` THEN
        ROLLBACK;
    ELSE
        COMMIT;
    END IF;
END$$

DELIMITER

In this example, for whatever reason, the insert into table c should fail (perhaps it doesn't have a date column).   our continue handler sets the variable _rollback to true, so then we rollback the transaction.  Otherwise, we commit the transaction.

Since the first 2 queries were successful, rollback will do the work for us of removing the rows that were added.

In the "resources" for this weeks section is a 7 minute youtube clip on MySQL Transactions, please watch it.

There are also 2 tutorials from different sources.  I suggest you review at least one of them.

Why Transactions?

The fundamental desire for a database is ACID compliance:

ACID

  • Atomicity − This ensures that all operations within the work unit are completed successfully; otherwise, the transaction is aborted at the point of failure and previous operations are rolled back to their former state.

  • Consistency − This ensures that the database properly changes states upon a successfully committed transaction.

  • Isolation − This enables transactions to operate independently on and transparent to each other.

  • Durability − This ensures that the result or effect of a committed transaction persists in case of a system failure.

A single query will lock the database so that all it's additions/changes/deletions are completed before another query can update or read data from the same table.

It would be bad if one query was changing 1 million rows and another query were reading those rows at the same time.  The one reading may not get the correct state of all the rows if some change before it read their data and after it's read other rows data.  With transactions it's important that changes to all tables relative to the are executed simultaneously so they won't affect other queries or transactions.

For this reason, it's important to be aware of the impact your transactions will have on the DB when they're executed.   If you have a transaction that will take a very long time to commit, many tables may be locked for a long time preventing other transactions or queries from executing. 

You may have noticed certain sites you visit might operate more slowly late at night than they do during the day.  In many cases, like your bank, for example, they run large batch process which can sometimes consist of bulky transactions and you're query to view your account statement may have to wait until they finish processing the transactions relative to your account from the past day.

Gotcha's

When using transactions it's very important to be aware of things that might perform actions when you didn't intend them.

Some statements cannot be rolled back, while others force an implicit commit. 

Any transaction with statements which create, drop, or alter a DB cannot be rolled back.   These really shouldn't be part of transactions but there are some use cases where this is done.

Since this statement can't be rolled back, any statements issued up to that point also can't be rolled back.  Those same statements force an implicit commit to all the transactions that happened before the statement.  

Similarly, drop, alter and create functions statements force an implicit commit and cannot be rolled back.

Be sure to understand the statements which cause an implicit commit.  Read the MySQL Documentation on implicit commit (Links to an external site.)Links to an external site..

A good rule of thumb is, if the query relates to "data" then it can be rolled back, if it relates to structures or code or metadata then it likely can't be rolled back and would also force an implicit commit.

猜你喜欢

转载自www.cnblogs.com/ecwork/p/8939304.html
今日推荐