什么是事务处理?事务处理用于维护数据库的完整性,它保证一批MySQL操作要么完全执行,要么不执行。
一、Mysql事务概念
MySQL事务主要用于处理运算量大、复杂度高的数据。一个逻辑执行单元由一步或多步数据库操作序列组成,这些操作序列要么全部执行,要么全部放弃。在MySQL中,只有使用Innodb数据库引擎的数据库或表支持事务。事务用于管理插入、更新和删除语句。
二、事务特性:
原子性、一致性、隔离性和耐久性。这四种特性也被称为酸性。1.原子性:事务是应用程序中最小的执行单位,就像原子是自然界中最小的粒子,具有不可分割的特性。它是事务应用、一组事务或成功中最小的逻辑执行器;或者撤回。
2.稳定性、一致性:作为事务执行的结果,数据库必须从一种一致性状态改变到另一种状态。当数据库只包含成功事务提交的结果时,数据库处于一致状态。原子性保证了一致性。有非法数据(如外键约束),交易撤销。
3.隔离:每个事务的执行互不干扰,任何事务的内部操作都与其他并发事务隔离。也就是说,并发事务看不到彼此的中间状态,并发事务也无法相互影响。事务独立运行。如果一个交易的结果影响到其他交易,那么其他交易将被撤回。100%隔离事务需要牺牲速度。
4.持久性、可靠性:持久性,也称为持久性,意味着一旦提交了事务,对数据的任何更改都必须记录在永久内存中,通常保存在物理数据库中。软硬件崩溃后,InnoDB数据表驱动会使用日志文件进行重构和修改。可靠性和高速是不能兼得的。innodb_flush_log_at_trx_commit选项决定何时将事务保存到日志中。
注意:存储引擎MyISAM不支持东西;存储引擎InnoDB支持。事务仅对影响数据的语句有效。显示引擎以查看mysql锁支持的数据引擎。
三、读取数据概念
1.脏读:脏读是指脏数据的读取,脏数据是指未提交的数据。事务正在修改记录。在该事务完成和提交之前,该数据处于未决状态(它可能被提交或回滚)。此时,第二个事务将读取这个未提交的数据,并相应地进一步处理它,从而产生未提交的数据依赖。这种现象被称为脏读。
2.不可重复读取:一个事务一个接一个地读取同一个记录,但是两次读取的数据不一样,所以我们称之为不可重复。也就是说,该事务的数据在两次读取之间被其他事务修改。
3.幻像读取:一个事务根据相同的查询条件重新读取以前检索到的数据,却发现其他事务插入了满足其查询条件的新数据。这种现象称为幻像读取。
四、事务隔离级别
修改事务隔离级别语法:
设置[会话|全局]事务隔离级别{未提交读取|提交读取|可重复读取|可序列化}
1.未提交读:这是最低的隔离级别,允许其他事务看到未提交的数据。这个水平会导致污读。如果一个事务已经开始写入数据,则不允许另一个事务同时写入,但允许其他事务读取该行数据。这种隔离级别可以通过“独占写锁”来实现。以避免更新丢失,但可能会出现脏读。也就是说,事务b已经读取了事务a的未提交数据.SELECT语句是以非锁定方式执行的,所以有可能读取脏数据,隔离级别最低。
将会话事务隔离级别设置为未提交读取;
设置全局事务隔离级别read uncommitted/*不要全局使用*/
SELECT @ @ global.tx _ isolation
SELECT @ @ session.tx _ isolation
SELECT @ @ tx _ isolation
创建一个新的简单的student表,设置id和name、num字段,并打开transaction 1。通过存储过程添加表,事务不会被提交。检查当前数据库事务状态,您可以看到事务级别为READ UNCOMMITTED的数据事务:
如果存在学生,则删除表;
创建表学生(
id int主键auto_increment注释 id ,
Name varchar(100)注释 Name ,
数字int
);
drop过程,如果存在proc _ on _ sw
分隔符;
创建过程proc_on_sw()
开始
开始交易;
插入到学生(姓名,编号)值( aaa ,1);
select * from information_schema。INNODB
结束
;
分隔符;
调用proc _ on _ SW();
创建新的事务2,并查询student表。我们可以在READ UNCOMMITTED级别看到其他事务的未提交数据:再次检查数据库事务状态,我们会看到状态正常。
开始交易;
select * from student
提交;
select * from information_schema。INNODB
2.Read Committed:读取数据的事务允许其他事务继续访问该行的数据,但未提交的write事务将禁止其他事务访问该行。这种隔离级别避免了脏读,但可能会出现不可重复的读。事务A预先读取数据,事务B立即更新数据并提交事务,当事务A再次读取数据时,数据已经发生了变化。
将会话事务隔离级别设置为已提交读取;
将全局事务隔离级别设置为已提交读取;/*不要全局使用*/
drop procedure if exist proc _ on _ up;
分隔符;
创建过程proc_on_up()
开始
设置自动提交=0;
更新学生集名称=cc ,其中id=1;
提交;
设置自动提交=1;
结束
;
分隔符;
调用proc _ on _ up();
select * from student
3.repeatable read:读取数据时(事务打开),不再允许修改操作,事务打开,不允许其他事务的更新修改操作。不可重复的读取对应于修改,即更新操作。然而,幻影阅读可能仍然存在问题。因为幻读问题对应的是插入操作,而不是更新操作。避免了重复读取和脏读取,但有时可能会出现幻影读取。这可以通过“共享读锁”和“独占写锁”来实现。
设置会话事务隔离级别可重复读取;
4.序列化,序列化:提供严格的事务隔离。它需要事务的串行执行。事务只能依次执行,不能并发执行。如果仅通过“行级锁”无法实现事务序列化,则必须采用其他机制来保证新插入的数据不会被刚刚执行查询操作的事务访问。序列化是最高的事务隔离级别,也是最昂贵的,性能较低,很少使用。在这个层次中,事务按顺序执行,不仅可以避免脏读、不可重复读,还可以避免幻影读。
设置可序列化的会话事务隔离级别;
隔离级别脏读、不可重复读、幻像读
未提交的读取是是是
阅读已提交否是是
可重复否否是
无序列化否否
动词(verb的缩写)完整的例子包括提交和回滚完整的例子。
drop过程,如果存在pro _ new
分隔符;
create procedure pro _ new(out RTN int)
开始
声明err INT default 0;
-如果发生异常,将自动处理并回滚。
声明sqlexception回滚的退出处理程序;
-开始交易。
设置自动提交=0;
开始交易;
插入到学生(姓名,人数)值(空,2.3);
-set err=@ @ IDENTITY;-=获取最后插入的自动增量ID;
set err=last _ insert _ id();-获取最后插入的自动增量ID。
插入学生(姓名,人数)值( ccc ,err);
-操作中没有异常,事务被提交。
提交;
-将返回值设置为1。
设置RTN=1;
设置自动提交=1;
结束
;
分隔符;
set @ n=1;
调用pro _ new(@ n);
选择@ n;