事务是一组有着内在逻辑联系的sql语句。
事务是对系统进行的操作,为了保证系统的完整性,
提示:下面的例子可能只有我自己能看懂,不懂可以问我。
还有MySQL5.0如何查看隔离级别由于我用的是8.0所以我没写出来 ,想知道可以评论提问。
**
1. 原子性:
** 事务是最小的单位,不可以在分割。
原子性是指数据库事务是不可分割的操作单位。
2. 一致性:
一个事务包括多个操作,这些操作要么全部执行,要么全部不执行。
一致性是指事务将数据库从一种状态变成另一种状态。在事务开始之前和事务结束之后,数据的完整性没有被破坏。
事务的一致性决定了一个系统设计和实现的复杂度。
3. 隔离性
隔离性要求每个读写事务的对象与其他事务的操作对象能相互分离,即该事务提交前对其他事务都不可见,通常使用锁来实现。
4、持久性:
事务一旦结束,就不可以返回。
事务提交对系统的永久的。
1.事务的四个隔离级别(后面有更详细):
1.未提交读
就是一个事务可以读取另一个未提交事务的数据
2. 已提交读
就是一个事务要等另一个事务提交后对读取数据。
3. 可重复读
开始读取数据,不再允许修改操作
4. 可序列化
在该级别下,事务串行化顺序执行。
(1). Redo 日志:
事务执行时需要将执行的事务日志写入到日志文件里,对应的文件为redo 日志。
当每条sql进行数据库更新操作时,首先将redo 日志写入到日志缓冲区, 当客户端执行commit 命令提交时,日志缓冲区的内容将被刷新到磁盘,日志缓冲区的刷新方式和时间间隔可以通过参数控制。
(2).undo日志:
与redo 日志相反,undo 日志主要用于事务异常时的数据回滚,具体内容就是复制事务前的数据库内容到undo 缓冲区,然后在合适的时间将内容刷新到磁盘。
1. read uncommitted; 读未提交的
2. read committed; 读已经提交的
3. repeatable read; 可以重复读
4.serializable; 串行化
1-1 read uncommitted
如果有事务a,和事务B,A事务对数据进行操作,在操作的过程 中,事务没有被提交,但是B可以看见a的操作的结果。
如何查看数据库的隔离级别:
Mysql 8.0
系统级别的
**Select @@global.transaction_isolation;**
会话级别的
**Select @@transaction_isolation;**
MYSQL 默认隔离级别:
Repeatable-read
修改隔离级别:
**set global(取键) transaction isolation level read 要修改的状态((un)committed);**
转账的一个例子:
start transaction ;
update user1 set money=money-800 where name='Ming';
update user1 set money=money+800 where name='TaoBao';
之后进行事务回滚,之前的数据就会不变。
如果两个不同的地方,都在进行操作,如果事务a 开启之后,他的数据可以被其他事务读取到 。
这样就会出现(脏读)
脏读:一个事务读到了另外一个事务没有提交的数据,就叫做脏读,(实际开发中不允许出现)
2. read committed; 读已经提交的
如何修改隔离级别:
set global(取键) transaction isolation level read 要修改的状态((un)committed);
然后查看:
**Select @@global.transaction_isolation;**
Start transaction;
Select * from user1;
虽然我只能读到另外一个事务提交的数据,但还是会出现问题,就是
读取同一个表的数据,发现前后不一致。
会出现不可重复读现象:read committed
3. repeatable read; 可以重复读
先修改隔离级别:
Set global transaction isolation level read committed;
Select @@global.transaction_isolation;
这个隔离级别会出现的问题:
这里会出现一个现象叫做幻读!!
事务A和事务B同时操作一张表,事务A提交的数据,也不能被事务B读到,就可以造成幻读。
4.serializable; 串行化
修改隔离级别为串行化:
Set global transaction isolation level serializable;
Select @@global.transaction_isolation;
Sql语句被卡住了
Mysql>insert into user1 values(8,’Ming’,200);
当user1 表被另外一个事务操作的时候,其他事务里面的写操作,是不可以进行的。
进入排队状态(串行化),指导a那边事务结束之后,b这个的写入操作才会执行。
串行化问题是,性能特差!!
Read-uncommitted > read-committed > repeatable-read > serializable;
隔离级别越高,性能越差。
Mysql 默认隔离级别是 Repeatable-read
1. 启动事务:
MySQL的事务是默认提交的,MySQL中使用start transaction 或 begin 语句可以显示控制一个事务的开始,
Start transaction
MySQL中不允许事务的嵌套。若在第1个事务中使用start transaction 命令,当第2 个事务开启时,系统会自动提交第1个事务。
2. 提交事务:
MySql使用commit 或者 commit work 语句提交事务。提交事务后,对数据库的修改是永久性的。
COMMIT;
3. 回滚事务:
MySQL中,使用rollback 或者rollback work 语句回滚事务,回滚事务会撤销正在进行的所有未提交的修改。语法:
Rollback
或者 xact_abort
回滚产生错误的Transact-SQL语句,而事务将继续进行处理,(注:错误严重或者语法错误时可能回滚整个事务)
4. 事务保存点:
除了启动事务,提交事务,回滚事务外,在事务中还可以设置保存点savepoint 可以将处理的事务回滚至保存点。
(1). Savepoint identifier
允许在事务中创建一个保存点,一个事务中可以有多个保存点。
(2). Release savepoint identifier
删除一个事务的保存点,当没有一个保存点时执行此语句会抛出一个异常。
(3). Rollback to identifier
如果给出savepoint ,可以把事务回滚到savepoint 指定的保存点,如果回滚到一个不存在的保存点,会抛出异常,如果不给出savepoint ,则回滚到启动事务之前的状态。