mysql之TCL:了解数据库语言之事务

声明:本博文如存在问题,欢迎各位dalao指正!!!

首先:what is TCL?
答:TRANSACTION Control LANGUAGE:事务控制语言

其次:what is 事务?
答:一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行。
如果说某条sql语句一旦执行失败或者产生错误,整个单元将会回滚。 举个栗子: zym转账500给ljf
数据库中要进行两个人账户之间金额的转账, 双方只有同时执行成功才能转账成功,否则就转账失败,这就是事务。

敲重点:事务的一些特性:
1.原子性,事务是一个不可分割的工作单位,要么都发生,要么都不发生。
2.一致性,事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
3.隔离性,事务的隔离性指的是一个事务的执行不能被其他事物干扰,即一个事务内部的操作及使用的数据对并发的其他的事务是隔离的,并发执行的各个事务之间不能进行互相干扰。
4.持久性,持久性是指一个事务一旦被提交,它对数据库的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。

一、事务的创建:

1.隐式事务:

事务没有明显的开启和结束的标志。默认为开。
例如insert,update,delete语句
因为这些语句都是开启了自动提交的事务。

2.显式事务:

事务有明显的开启和提交功能
多条语句时,必须先设置自动提交功能为禁用。

三个步骤:

  • 开启事务的语句:
    set autocommit=0;
    start transaction;可以选择写或不写。
  • 编写事务中的语句:sql语句:
    UPDATE 表 Set 余额=500 WHERE 用户名=‘zym’;
    [savepoint 节点名:可以在语句中间设置保存点,只搭配结束语句为Rollback语句使用,结果回滚到保存点]
    UPDATE 表 Set 余额=1500 WHERE 用户名=‘ljf’;
  • 结束事务的语句: commit,提交事务; ROLLBACK,回滚事务.

案例演示:

-- 开始事务
set autocommit=0;
start TRANSACTION;
-- 编写事务的语句
UPDATE account set balance=500 where name='zym';
UPDATE account SET balance=1500 where name='ljf';
-- 结束事务
COMMIT;

二、事务并发问题

1.脏读:

例如对于两个事务t1,t2; t1读取了已经被t2更新的数据,但是t2还没有提交;之后若t2回滚,t1再读取,t1读取的内容就会变回t2更改之前的数据。(读未提交数据)
说明一下:在事务未提交之前,事务的处理结果都是保存在内存当中的;若事务成功提交,就会将结果保存到磁盘当中去,反之事务提交失败,数据就会回滚,并不改变磁盘中数据库的数据。

2.不可重复读:

对于两个事务t1,t2;t1更改了一个数据但是没有提交,然后后t2查询了数据,会发现数据没有改变,之后t1提交了事务,t1再次读取数据,数据又发生了改变。
(读已提交数据)

3.幻读:

例如对于两个事务t1,t2;t1先查询一个表的数据有2条,t1修改表中所有数据name为zym,但是它没提交事务;然后同时t2又在该表中插入了一条新的数据并已经提交;然后t2再进行提交,就会发现改变的数据是3条(可重复读)

解决方案:数据库提供的4种事务隔离级别:
(mysql默认为第三个隔离级别,oracle默认为第二个级别)

  1. 读未提交数据(READ UNCOMMITTED):
    允许事务读取未被其他事务提交的变更,脏读、不可重复读和幻读的问题都会出现。
  2. 读已提交数据(READ COMMITTED):
    只允许事务读取已经被其他事务提交的变更,可以避免脏读,但不可重复读和幻读问题仍然可能出现。
  3. 读可重复读数据(REPEATABLE READ):
    确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新,可以避免脏读和不可重复读,但幻读的问题仍然存在。
  4. 串行化(SERIALIZABLE):
    确保事务可以多次从一个表中读取相同的行。在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,所有的并发问题都可以避免,但性能十分低下
查看当前的隔离级别:
SELECT @@tx_isolation;
设置当前mysql连接的隔离级别:
SET TRANSACTION ISOLATION LEVEL READ committed;
设置数据库系统的全局的隔离级别:
SET GLOBAL TRANSACTION ISOLATION LEVEL READ committed;

三、关于隔离级别的思考?

按理说串行化的隔离级别最高,不会产生任何事务并发问题;但是其他的隔离级别也有其存在的必要,比如说脏读就让我想起qq的撤回功能,可能我们发送的消息发送后的一段时间内都是保存在内存里的,并未提交到数据库当中去,所以可以撤回消息,另外还可以减少数据库的读写操作,提升数据库的并发性能。

发布了53 篇原创文章 · 获赞 16 · 访问量 9261

猜你喜欢

转载自blog.csdn.net/Zheng_lan/article/details/105225196