MySQL中使用事务处理保证数据的完整性,银行转账过程中为了避免数据出错,通常使用事务处理的方式来进行处理。MYISAM不支持事务高级处理,InnoDB支持;
事务是一组mysql语言放在同一批次来处理。若有一条mysql语言错误,则这一批次sql都被取消执行。
(1)事务的ACID原则:
(CRUD?)
原子性(A):执行事务要么都成功,要么都不成功;
一致性(C):执行后保证数据的一致;
独立性(I):各个事务之间相互独立,互不影响;
持久性(D):事务的数据可以永久存储在数据库中;
(2)关于事务的sql语言:
查询事务的默认提交方式:select@@autocommit;
select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
关闭事务的自动提交方式:set autocommit=0;
select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
开启事务的自动提交方式:set autocommit=1;
set autocommit=1;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
事务处理流程:
1、关闭事务自动提交方式:set autocommit=0;
2、开启一个事务,标记事务的起始点:start transaction 或者begin;
3、一系列操作SQL语言,例如更新表的一个数据:update class set name='lily' where id='20003';
4、提交事务或者事务出错回滚:commit或者rollback;
5、还原mysql的自动提交方式:set autocommit=1;
查看事务默认隔离级别:
select @@tx_isolation;读取当前事务
select @@global.tx_isolation;读取全局事务
select @@session.tx_isolation;读取当前事务
例子:
set tx_isolation='read-uncommitted';
Query OK, 0 rows affected (0.00 sec)
select @@tx_isolation;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set (0.00 sec)
mysql> select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ |
+-----------------------+
1 row in set (0.00 sec)
mysql> select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| READ-UNCOMMITTED |
+------------------------+
1 row in set (0.00 sec)
修改当前会话事务默认隔离级别:set tx_isolation='read-uncommitted';
修改全局事务隔离级别:set global.tx_isolation='read-uncommitted';
(3)事务的隔离级别:
读取未提交:read-uncommitted;
读取提交:read-committed;
重复读取:repeatable-read;(默认的事务隔离级别)
串行化():加锁--竞争锁;
(4)处理事务时出现的问题:(
如何处理脏读和幻读的问题)
1、脏读:当一个事务在执行时没有提交,另一个事务查看数据时将刚才未提交的数据查询到;
2、幻读:读取到数据,因为某一个事务的原因导致刚才的数据消失;
举例:
客户A购买一款商品,价格500.00,网银转账支付。A账户余额2000.00,向卖家B转账500.00,B账户起始金额为10000.00;
创建数据库和表;
create database shop;
use shop;
create table account(id int not null primary key auto_increment,name varchar(32) not null,cash decimal(9.2) not null);
插入数据:
insert into account(name,cash)values('A',2000.00),('B',10000.00);
mysql> update account set cash=cash-100 where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from account ;
+----+------+----------+
| id | name | cash |
+----+------+----------+
| 1 | A | 1900.00 |
| 2 | B | 10500.00 |
+----+------+----------+
2 rows in set (0.00 sec)
mysql> update account cash=cashh+100 where id=2;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '=cashh+100 where id=2' at line 1
mysql> rollback;
Query OK, 0 rows affected (0.08 sec)
mysql> select * from account;
+----+------+----------+
| id | name | cash |
+----+------+----------+
| 1 | A | 2000.00 |
| 2 | B | 10500.00 |
+----+------+----------+
2 rows in set (0.00 sec)