新闻中心

mysql事务使用

mysql事务使用

MySQL 事务 | 菜鸟教程

MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

一般来说,事务是必须满足4个条件(ACID)::原子性(

tomicity,或称不可分割性)、一致性(

onsistency)、隔离性(

solation,又称独立性)、持久性(

urability)。

一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。

BEGIN 或 START TRANSACTION 显式地开启一个事务;

COMMIT 也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改成为永久性的;

ROLLBACK 也可以使用 ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;

SAVEPOINT identifier,SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT;

RELEASE SAVEPOINT identifier 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;

ROLLBACK TO identifier 把事务回滚到标记点;

SET TRANSACTION 用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。

1、用 BEGIN, ROLLBACK, COMMIT来实现

2、直接用 SET 来改变 MySQL 的自动提交模式:

   codeDonald

  113***2348@qq.com

savepoint 是在数据库事务处理中实现“子事务”(subtransaction),也称为嵌套事务的方法。事务可以回滚到 savepoint 而不影响 savepoint 创建前的变化, 不需要放弃整个事务。

ROLLBACK 回滚的用法可以设置保留点 SAVEPOINT,执行多条操作时,回滚到想要的那条语句之前。

使用 SAVEPOINT

删除 SAVEPOINT

保留点再事务处理完成(执行一条 ROLLBACK 或 COMMIT)后自动释放。

MySQL5 以来,可以用:

   codeDonald

  113***2348@qq.com

mysql事务的使用 - zezhou222 - 博客园

(1) 为了保证的数据的安全.

比如:转钱的场景,A转给B 100, A-100,B+100有两步操作,开启事务后两步骤都完成才会完整的写入数据库,否则执行回滚操作回到原始状态。

 

(2) 涉及多张表的操作时候(比如表是有关联的)

删除这种有关联的,如果某张表删除数据出错,那前面已经删除的关联表就没数据了,下次删除就又可能出现其它问题,所以通过事务可以解决这个问题,要么都删除成功,要不都不动。

 

# 摘得

 

 # 默认mysql开启了自动提交,在执行insert,update,delete语句时候每一条sql语句就是一个事务。

操作:

注:在事务开启后可执行任何其他操作,遇到commit;才会写入至硬盘,遇到rollback会回滚到事务开启的那个时候

 

排他锁(行锁)的使用:

 

如何使用MySQL事务 - MySQL数据库 - 亿速云

分享文章到朋友圈

这篇文章主要为大家展示了如何使用

事务,内容简而易懂,希望大家可以学习一下,学习完之后肯定会有收获的,下面让小编带大家一起来看看吧。

事务是通过事务日志来实现的,事务日志包括:redo log和undo log。

当回滚操作执行完毕时,也就是数据库恢复到了执行事务之前的状态,我们就说该事务处在了中止的状态。

1. 读未提交(Read uncommitted)

2. 读提交(Read committed)

3. 可重复读(Repeatable read)

4. 串行化(Serializable)

1. 从老王媳妇账户读取数据

2. 从老王媳妇账户上减掉20元

3. 从老王账户读取数据

4. 给老王账户增加20元

5. 执行提交成功

6. 此时老王媳妇账户只有80元啦,而老王账户有30元啦,老王高兴不得了咯

1. 从老王媳妇账户读取数据

2. 从老王媳妇账户上减掉25元

3. 从老王账户读取数据

4. 给老王账户增加25元

5. 此时老王媳妇撤回之前的操作

6. 此时,老王和老王媳妇的账户余额还是保持操作之前的数目

此时需要操作事务,则需要显式开启(begin or start transaction)和提交(commit)或回滚(rollback)。

如设置成OFF,则需要执行提交(commit)或回滚(rollback)操作时才会真正执行事务。

当我们使用ALTER USER、CREATE USER、DROP USER、GRANT、RENAME USER、REVOKE、SET PASSWORD等语句时也会隐式的提交前边语句所属于的事务。

当我们在一个事务还没提交或者回滚时就又使用START TRANSACTION或者BEGIN语句开启了另一个事务时,会隐式的提交上一个事务。

或者使用LOCK TABLES、UNLOCK TABLES等关于锁定的语句也会隐式的提交前边语句所属的事务。

有了事务的保存点,我们在进行复杂的事务操作时,我们不用担心一出错直接回滚到最初状态,就如一夜回到解放前。

1. SAVEPOINT 保存点名称;//标记保存点

2. ROLLBACK TO [SAVEPOINT] 保存点名称;//回滚到某一个保存点

3. RELEASE SAVEPOINT 保存点名称;//删除

以上就是关于如何使用MySQL事务的内容,如果你们有学习到知识或者技能,可以把它分享出去让更多的人看到。

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

红包可用于(云服务器、高防服务器、裸金属服务器、高防IP、云数据库、CDN加速)购买和续费

Copyright © Yisu Cloud Ltd. All Rights Reserved. 2018 版权所有

mysql事务的使用_小林的博客-CSDN博客_mysql 事务

 

 

三、MySQL事务隔离级别

mysql默认的事务隔离级别为repeatable-read

 

四、用例子说明各个隔离级别的情况

  1、读未提交:

    (1)打开一个客户端A,并设置当前事务模式为read uncommitted(未提交读),查询表account的初始值:

 

    (2)在客户端A的事务提交之前,打开另一个客户端B,更新表account:

 

 

    (3)这时,虽然客户端B的事务还没提交,但是客户端A就可以查询到B已经更新的数据:

 

    (4)一旦客户端B的事务因为某种原因回滚,所有的操作都将会被撤销,那客户端A查询到的数据其实就是脏数据:

 

     (5)在客户端A执行更新语句update account set balance = balance - 50 where id =1,lilei的balance没有变成350,居然是400,是不是很奇怪,数据不一致啊,如果你这么想就太天真 了,在应用程序中,我们会用400-50=350,并不知道其他会话回滚了,要想解决这个问题可以采用读已提交的隔离级别

 

  2、读已提交

    (1)打开一个客户端A,并设置当前事务模式为read committed(未提交读),查询表account的所有记录:

 

    (2)在客户端A的事务提交之前,打开另一个客户端B,更新表account:

 

    (3)这时,客户端B的事务还没提交,客户端A不能查询到B已经更新的数据,解决了脏读问题:

 

    (4)客户端B的事务提交

    (5)客户端A执行与上一步相同的查询,结果 与上一步不一致,即产生了不可重复读的问题

 

   3、可重复读

     (1)打开一个客户端A,并设置当前事务模式为repeatable read,查询表account的所有记录

    (2)在客户端A的事务提交之前,打开另一个客户端B,更新表account并提交

    (3)在客户端A查询表account的所有记录,与步骤(1)查询结果一致,没有出现不可重复读的问题

    (4)在客户端A,接着执行update balance = balance - 50 where id = 1,balance没有变成400-50=350,lilei的balance值用的是步骤(2)中的350来算的,所以是300,数据的一致性倒是没有被破坏。可重复读的隔离级别下使用了MVCC机制,select操作不会更新版本号,是快照读(历史版本);insert、update和delete会更新版本号,是当前读(当前版本)。

(5)重新打开客户端B,插入一条新数据后提交

(6)在客户端A查询表account的所有记录,没有 查出 新增数据,所以没有出现幻读

 

  4.串行化

    (1)打开一个客户端A,并设置当前事务模式为serializable,查询表account的初始值:

    (2)打开一个客户端B,并设置当前事务模式为serializable,插入一条记录报错,表被锁了插入失败,mysql中事务隔离级别为serializable时会锁表,因此不会出现幻读的情况,这种隔离级别并发性极低,开发中很少会用到。

  

 

扫一扫,分享内容

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。

2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

漫谈MySQL九-MySQL中事务的使用_b379685397的博客-CSDN博客

大家好,我是王老狮,上篇我们简单了解了什么是事务,今天我们就来具体聊聊,事务在SQL中是如何使用的吧。

SQL 标准中规定,针对不同的隔离级别,并发事务可以发生不同严重程度的 问题,具体情况如下:

 

只对当前会话的所有后续的事务有效

transaction_isolation 的值来确定:

 

 注 意 :

事务的提交有三种方式

rollback

commit

扫一扫,分享内容

打赏作者

王老狮

你的鼓励将是我创作的最大动力

您的余额不足,请更换扫码支付或

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。

2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

MySQL数据库——事务的操作(开启、回滚、提交)、特征、隔离级别基础总结 - 云+社区 - 腾讯云

分享文章到朋友圈

海报分享

如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。如下A给B转钱的例子很形象的说明了事务的概念:

【举例】:还是用这个A给B转账的例子,在SQLyog中进行模拟开启事务、回滚、提交

1)在A窗口中先开启事务,然后执行张三账户-500,-》出错了-》李四账户+500,此时查询A窗口数据,张三确实-500,但李四还是100;在B窗口中查询数据,张三和李四都是1000,没发生变化;说明A窗口中开启事务起了作用,且A中查询的数据也只是暂时的。

2)发现错误后,执行回滚操作,再次在窗口A和B中查询,数据都是1000,回滚操作成功。

3)在A窗口中先开启事务,然后执行张三账户-500-》李四账户+500,此时查询A窗口数据,张三确实-500,李四+500;在B窗口中查询数据,张三和李四都是1000,没发生变化;因在A窗口中的操作都OK,执行提交事务,再次在窗口A和B中查询,数据都发生正确变化,事务提交成功。

1)事务提交的两种方式

2)修改事务的默认提交方式

实际上手动控制事务的开启与提交,可以大幅度提高数据插入的效率,在进行数据批量插入操作时可以手动控制事务。

1)原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败;

2)持久性:事务一旦提交或回滚,数据表的数据将被持久化的保存;

3)隔离性:多个事务之间相互独立;

4)一致性:表示事务操作前后,数据总量不变。

多个事务之间是隔离的,相互独立的,但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别,就可以解决这些问题。

1)脏读:一个事务读取到另一个事务中没有提交的数据; 【举例】:A给B发1000块钱,手一抖打了10000,这个钱已经打到B的户口,但是事务还没有提交,这时B查下卡,发现多了9000,兴奋坏了,但是A及时发现,马上回滚差点提交的事务,将数字改回1000再提交。

2)不可重复读(虚读):在同一个事务中两次读取到的数据不一样; 【举例】:A拿着卡去购物,卡里有1000块钱,当A买单时(事务开启),收费系统事先检测到他的卡里有1000,就在这个时候,A的妻子要把钱全部拿出来买首饰,并提交。当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了(第二次检测金额当然要等待A的妻子转出金额事务提交完),A就会很郁闷,钱哪去了。。。

3)幻读:一个事务操作(DML)数据表中所有的记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改; 【举例】:A去消费,花了1千元,A的妻子去查看他今天的消费记录(全表扫描FTS,妻子事务开启),看到确实是花了1千元,就在这时,A又花了1千元买了一个机械键盘,即新增INSERT了一条消费记录,并提交。当妻子打印消费记录清单时(妻子事务提交),发现花了2千元,似乎出现了幻觉,这就是幻读。

     【会产生的问题】:脏读、不可重复读、幻读

    【会产生的问题】:不可重复读、幻读

    【会产生的问题】:幻读

    【会产生的问题】:可以解决所有问题

【注意】:隔离级别从小到大,安全性越来越高,但是效率越来越低。但是一般情况下不会修改数据库默认的隔离级别,只有在极特殊情况下才会做出修改已解决一些特殊问题。

数据库查询隔离级别:select  @@tx_isolation;

数据库设置隔离级别:set global transaction isolation level 级别字符串;

———————————————————————————————————————

本文为博主原创文章,转载请注明出处!

本文参与

,欢迎正在阅读的你也加入,一起分享。

在学习《MySQL技术内幕:SQL编程》一书,并做了笔记。本博客内容是自己学了《MySQL技术内幕:SQL编程》事务编程一章之后,根据自己的理解做的笔记,内容和...

作为一个后端工程师,想必没有人没用过数据库,跟我一起复习一下MySQL吧,本文是我学习《MySQL实战45讲》的总结笔记的第二篇,总结了MySQL的事务隔离级别...

数据库中的事务是指对数据库执行一批操作,这些操作最终要么全部执行成功,要么全部失败,不会存在部分成功的情况。

如果一个包含多个步骤的业务操作,这些操作被事务管理,那么这些操作要么同时成功要么同时失败

1. 概念: 如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。 2. 操作: 1. 开启事务:st...

事务(Transaction)是并发控制的基本单位。所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。事务处理可以确保...

相信大家都用过事务以及了解他的特点,如原子性(Atomicity),一致性(Consistency),隔离型(Isolation)以及持久性(Durabilit...

  简单说,事务就是一组原子性的SQL执行单元。如果数据库引擎能够成功地对数据库应 用该组査询的全部语句,那么就执行该组SQL。如果其中有任何一条语句因为崩溃或...

前言   这段时间自己会把之前学的东西都总结一遍,希望对自己以后的工作中有帮助。其实现在每天的状态都是很累的,但是我要坚持!   进入我们今天的正题:   为什...

了解事务之前,先来看看数据库为什么需要有事务,假设没有事务会有什么影响?假设我们有一个银行账户系统,表结构如下:

提到事务,你肯定不陌生,和数据库打交道的时候,我们总是会用到事务。最经典的例子就是转账,你要给朋友小王转 100 块钱,而此时你的银行卡只有 100 块钱。

ACID原则是数据库事务正常执行的四个基本要素,分别指原子性、一致性、隔离性及持久性。

所谓事务是用户自定义的一个数据库操作序列,这些操作是一个不可分割的单位。我们要知道,事务 和 程序 是两个概念,一般来讲,一个程序中包含多个事务。

数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。事务的使用是数据库管理系统区别文件系统的重要特征之一。

ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性 -Atomicity(原子性...

在如今互联网业务中使用范围最广的数据库无疑还是关系型数据库MySQL,之所以用"还是"这个词,是因为最近几年国内数据库领域也取得了一些长足进步,例如以TIDB、...

在如今互联网业务中使用范围最广的数据库无疑还是关系型数据库MySQL,之所以用"还是"这个词,是因为最近几年国内数据库领域也取得了一些长足进步,例如以TIDB、...

如果在执行一个业务操作的时候,需要执行多条SQL语句,必须保证所有的SQL语句都执行成功。只要其中有一条执行失败,则所有的SQL语句都要进行回滚

Copyright © 2013 - 2022 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有

扫码关注云+社区

领取腾讯云代金券

MySQL事务的使用 - lin_zone - 博客园

在上篇文章

中已经提到了事务的特性、事务的隔离级别及各个隔离级别可能导致的问题,下面来说说MySQL中事务的使用

MySQL 事务简单使用

在代码里使用事务前

MySQL 分布式事务 参考:

对于有关联的数据的处理有时候可能不在一个数据库中,这个时候如果想要保证数据绝对可靠,就需要考虑使用分布式事务了。

XA协议

XA规范中分布式事务有AP,RM,TM组成:

Xa主要规定了RM与TM之间的交互,XA规范中定义的RM 和 TM交互的接口:

xa_start负责开启或者恢复一个事务分支,并且管理XID到调用线程

xa_end 负责取消当前线程与事务分支的关联

xa_prepare负责询问RM 是否准备好了提交事务分支

xa_commit通知RM提交事务分支

xa_rollback 通知RM回滚事务分支

XA协议使用了二阶段协议

MySQL中XA实现

通过 show engines; 可以看到 只有InnoDB存储引擎支持XA事务

在MySQL数据库分布式事务中,MySQL是XA事务过程中的资源管理器(RM)存在的,TM是连接MySQL服务器的客户端。MySQL数据库是作为RM存在的,在分布式事务中一般会涉及到至少两个RM。需要注意的是MySQL中只有当隔离级别为Serializable时候才能使用分布式事务,所以需要使用

设置数据库隔离级别

MySQL 中使用XA

其中首先使用XA START ‘xid' 启动了一个XA事务,并把它置于ACTIVE状态

对于一个ACTIVE状态的 XA事务,我们可以执行构成事务的多条SQL语句,也就是指定分支事务的边界,然后执行一个XA END ‘xid'语句,XA END把事务放入IDLE状态,也就是结束事务边界,在xa start和xa end之间的语句就构成了本分支事务的一个事务范围。当调用xa end 'xid1'后由于结束了事务边界,所以这时候如果再执行sql语句会抛出ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the IDLE state错误,也就是当分支事务处于IDLE状态时候不允许执行没有包含到分支事务边界里面的其他SQL.

对于一个IDLE 状态XA事务,可以执行一个XA PREPARE语句或一个XA COMMIT…ONE PHASE语句,其中XA PREPARE把事务放入PREPARED状态。在此点上的XA RECOVER语句将在其输出中包括事务的xid值,因为XA RECOVER会列出处于PREPARED状态的所有XA事务。XA COMMIT…ONE PHASE用于预备和提交事务,也就是转换为一阶段协议,直接提交事务。

对于一个PREPARED状态的 XA事务,可以执行XA COMMIT 语句来提交或者执行XA ROLLBACK来回滚xa事务。

分布式事务的几个解决方案 参考:

TCC补偿模式

TCC 方案是二阶段提交的 另一种实现方式,它涉及 3 个模块,主业务、从业务和 活动管理器(协作者)

第一阶段:主业务服务分别调用所有从业务服务的 Try 操作,并在活动管理器中记录所有从业务服务。当所有从业务服务 Try 成功或者某个从业务服务 Try 失败时,进入第二阶段。

第二阶段:活动管理器根据第一阶段从业务服务的 Try 结果来执行 Confirm 或 Cancel 操作。如果第一阶段所有从业务服务都 Try 成功,则协作者调用所有从业务服务的 Confirm 操作,否则,调用所有从业务服务的 cancel 操作。

在第二阶段中,Confirm 和 Cancel 同样存在失败情况,所以需要对这两种情况做异常处理以保证数据一致性。

Confirm 失败:则回滚所有 Confirm 操作并执行 Cancel 操作。Cancel 失败:从业务服务需要提供自动重试 Cancel 机制,以保证 Cancel 成功。

注:这种方案实现的要素在于,调用链需要被记录,且每个服务提供者都需要提供一组业务逻辑相反的操作,互为补偿,同时回滚操作和确认提交操作要

消息队列可靠消息提交

利用消息队列,需要执行的操作的时候 产生一条可靠的消息到消息队列,然后可靠地消费这个消息。通过 消息队列的消息完成最终的一致性

以转账服务为例,当支付宝账户扣除1万后,我们只要生成一个凭证(消息)即可,这个凭证(消息)上写着“让余额宝账户增加 1万”,只要这个凭证(消息)能可靠保存,我们最终是可以拿着这个凭证(消息)让余额宝账户增加1万的,即我们能依靠这个凭证(消息)完成最终一致性。

如何可靠保存凭证(消息):

  1)支付宝在扣款事务提交之前,向实时消息服务请求发送消息,实时消息服务只记录消息数据,而不真正发送,只有消息发送成功后才会提交事务; ( 相当于先准备了一个消息,但是不能被消费)

  2)当支付宝扣款事务被提交成功后,向实时消息服务确认发送。只有在得到确认发送指令后,实时消息服务才真正发送该消息;

  3)当支付宝扣款事务提交失败回滚后,向实时消息服务取消发送。在得到取消发送指令后,该消息将不会被发送;

  4)对于那些未确认的消息或者取消的消息,需要有一个定时任务 定时去支付宝系统查询这个消息的状态并进行更新。为什么需要这一步骤,举个例子:假设在第2步支付宝扣款事务被成功提交后,系统挂了,此时消息状态并未被更新为“确认发送”,从而导致消息不能被发送。

  优点:消息数据独立存储,降低业务系统与消息系统间的耦合;

  缺点:一次消息发送需要两次请求;业务处理服务需要实现消息状态回查接口。

如何解决消息重复投递的问题:

  还有一个很严重的问题就是消息重复投递,以我们支付宝转账到余额宝为例,如果相同的消息被重复投递两次,那么我们余额宝账户将会增加2万而不是1万了。

  为什么相同的消息会被重复投递?比如余额宝处理完消息msg后,发送了处理成功的消息给实时消息服务,正常情况下实时消息服务应该要删除消息msg,但如果实时消息服务这时候悲剧的挂了,重启后一看消息msg还在,就会继续发送消息msg。

  解决方法很简单,消费消息做到幂等性,在余额宝这边增加消息应用状态表(message_apply),通俗来说就是个账本,用于记录消息的消费情况,每次来一个消息,在真正执行之前,先去消息应用状态表中查询一遍,如果找到说明是重复消息,丢弃即可,如果没找到才执行,同时插入到消息应用状态表(同一事务)。

阿里开源分布式中间件 Seata —— 标准分布式模型 TXC

Seata 内部定义了 3个模块来处理全局事务和分支事务的关系和处理过程,这三个组件分别是:

Transaction Coordinator (TC):事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。

Transaction Manager (TM):事务的发起者,控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。

Resource Manager (RM):负责控制每个服务的分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。

简要说说整个全局事务的执行步骤:

TM 向 TC 申请开启一个全局事务,TC 创建全局事务后返回全局唯一的 XID,XID 会在全局事务的上下文中传播;

RM 向 TC 注册分支事务,该分支事务归属于拥有相同 XID 的全局事务;

TM 向 TC 发起全局提交或回滚;

TC 调度 XID 下的分支事务完成提交或者回滚。

相对于XA ,Seata 优化了锁定的机制。RM 到 TC 控制器端查询操作的本地数据这一行是否被全局锁定了,如果被锁定了,就重新尝试,如果没被锁定,则加全局锁后开始解析 SQL,把业务数据在更新前后的数据镜像组织成回滚日志,并将 undo log 日志插入 undo_log 表中,保证每条更新数据的业务 sql 都有对应的回滚日志存在。这样做的好处就是,本地事务执行完可以立即释放本地事务锁定的资源,然后向 TC 上报分支状态。当 TM 决议全局提交时,就不需要同步协调处理了,TC 会异步调度各个 RM 分支事务删除对应的 undo log 日志和全局锁,这个步骤非常快速地可以完成;当 TM 决议全局回滚时,RM 收到 TC 发送的回滚请求,RM 通过 XID 找到对应的 undo log 回滚日志,然后执行回滚日志完成回滚操作。

分支事务中数据的 本地锁 由本地事务管理,在分支事务 Phase1 结束时释放。同时,随着本地事务结束,连接也得以释放。

分支事务中数据的 全局锁 在事务协调器侧 TC 管理,在决议 Phase2 全局提交时,全局锁马上可以释放。只有在决议全局回滚的情况下,全局锁才被持有至分支的 Phase2 结束。

这个设计,极大地减少了分支事务对资源(数据和连接)的锁定时间,给整体并发和吞吐的提升提供了基础。

注:本文参考多篇文章,可以作为一个了解的知识(奈何我水平太低,后面的内容我暂时还没能完全参透)。

      本文整理不易,如需转载请注明出处,

MySQL事务【详解-最新的总结】_wang_luwei的博客-CSDN博客

数据库中的事务是指对数据库执行一批操作,在同一个事务当中,这些操作最终要么全部执行成功,要么全部失败,不会存在部分成功的情况。

举个例子:

比如A用户给B用户转账100操作,过程如下:

如果在事务的支持下,上面最终只有2种结果:

如果没有事务的支持,可能出现错:A账户减少了100,此时系统挂了,导致B账户没有加上100,而A账户凭空少了100。

事务的整个过程如原子操作一样,最终要么全部成功,或者全部失败,这个原子性是从最终结果来看的,从最终结果来看这个过程是不可分割的。

一个事务必须使数据库从一个一致性状态变换到另一个一致性状态。

首先回顾一下一致性的定义。所谓一致性,指的是数据处于一种有意义的状态,这种状态是

的而不是

的。最常见的例子是转帐。例如从帐户A转一笔钱到帐户B上,如果帐户A上的钱减少了,而帐户B上的钱却没有增加,那么我们认为此时数据处于不一致的状态。

一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

一个事务一旦提交,他对数据库中数据的改变就应该是永久性的。当事务提交之后,数据会持久化到硬盘,修改是永久性的。

mysql中事务默认是隐式事务,执行insert、update、delete操作的时候,数据库自动开启事务、提交或回滚事务。

是否开启隐式事务是由变量autocommit控制的。

所以事务分为

事务自动开启、提交或回滚,比如insert、update、delete语句,事务的开启、提交或回滚由mysql内部自动控制的。

查看变量autocommit是否开启了自动提交

autocommit为ON表示开启了自动提交。

事务需要手动开启、提交或回滚,由开发者自己控制。

2种方式手动控制事务:

语法:

示例1:提交事务操作,如下:

示例2:回滚事务操作,如下:

可以看到上面数据回滚了。

我们把autocommit还原回去:

语法:

示例1:提交事务操作,如下:

上面成功插入了2条数据。

示例2:回滚事务操作,如下:

上面事务中我们删除了test1的数据,显示删除了3行,最后回滚了事务。

在事务中我们执行了一大批操作,可能我们只想回滚部分数据,怎么做呢?

我们可以将一大批操作分为几个部分,然后指定回滚某个部分。可以使用savepoin来实现,效果如下:

先清除test1表数据:

演示savepoint效果,认真看:

从上面可以看出,执行了2次插入操作,最后只插入了1条数据。

savepoint需要结合rollback to sp1一起使用,可以将保存点sp1到rollback to之间的操作回滚掉。

表示在事务中执行的是一些只读操作,如查询,但是不会做insert、update、delete操作,数据库内部对只读事务可能会有一些性能上的优化。

用法如下:

示例:

只读事务中执行delete会报错。

丢失更新就是两个不同的事务(或者Java程序线程)在某一时刻对同一数据进行读取后,先后进行修改。导致第一次操作数据丢失。

第一类丢失更新 :A,B 事务同时操作同一数据,A先对改数据进行了更改,B再次更改时失败然后回滚,把A更新的数据也回滚了。(事务撤销造成的撤销丢失)

第二类丢失更新:A,B 事务同时操作同一数据,A先对改数据进行了更改,B再次更改并且提交,把A提交的数据给覆盖了。(事务提交造成的覆盖丢失)

一个事务在执行的过程中读取到了其他事务还没有提交的数据。 这个还是比较好理解的。

两个事务同时操作同一数据,A事务对该数据进行了修改还没提交的时候,B事务访问了该条事务,并且使用了该数据,此时A事务回滚,那么B事务读到的就是脏数据。

比如事务1,修改了某个数据 事务2,刚好访问了事务1修改后的数据

此时事务1,回滚了操作 事务2,读到还是回滚前的数据

从字面上我们就可以理解,即一个事务操作过程中可以读取到其他事务已经提交的数据。

事务中的每次读取操作,读取到的都是数据库中其他事务已提交的最新的数据(相当于当前读)

在同一事务中,多次读取同一数据返回的结果有所不同,换句话说,后续读取可以读到另一事务已提交的更新数据。相反,“可重复读” 在同一事务中多次读取数据时, 能够保证所读数据一样, 也就是后续读取不能读到另一事务已提交的更新数据。

这种情况发生 在一个事务内多次读同一数据。A事务查询某条数据,该事务未结束时,B事务也访问同一数据并进行了修改。那么在A事务中的两 次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。

事务1,查询某个数据 事务2,修改了某个数据,提交

事务1,再次查询这个数据

这样事务1两次查询的数据不一样,称为不可重复读

一个事务操作中对于一个读取操作不管多少次,读取到的结果都是一样的。

脏读、不可重复读、可重复读、幻读,其中最难理解的是幻读

以mysql为例:

幻读现象例子:

看第二种解释:

如果还是理解不了的,继续向下看,后面后详细的演示。

当多个事务同时进行的时候,如何确保当前事务中数据的正确性,比如A、B两个事物同时进行的时候,A是否可以看到B已提交的数据或者B未提交的数据,这个需要依靠事务的隔离级别来保证,不同的隔离级别中所产生的效果是不一样的。

上面4中隔离级别越来越强,会导致数据库的并发性也越来越低。

分2步骤,修改文件、重启mysql,如下:

修改mysql中的my.init文件,我们将隔离级别设置为:READ-UNCOMMITTED,如下:

以管理员身份打开cmd窗口,重启mysql,如下:

表格中和网上有些不一样,主要是幻读这块,幻读只会在可重复读级别中才会出现,其他级别下不存在。

下面我们来演示一下,各种隔离级别中可见性的问题,开启两个窗口,叫做A、B窗口,两个窗口中登录mysql。

将隔离级别置为READ-UNCOMMITTED:

重启mysql:

查看隔离级别:

先清空test1表数据:

按时间顺序在2个窗口中执行下面操作:

A窗口如下:

B窗口如下:

看一下:

T2-A:无数据,T6-A:有数据,T6时刻B还未提交,此时A已经看到了B插入的数据,

T2-A:无数据,T6-A:有数据,查询到的结果不一样,

将隔离级别置为READ-COMMITTED

重启mysql:

查看隔离级别:

先清空test1表数据:

按时间顺序在2个窗口中执行下面操作:

A窗口如下:

B窗口如下:

看一下:

T5-B:有数据,T6-A窗口:无数据,A看不到B的数据,

T6-A窗口:无数据,T8-A:看到了B插入的数据,此时B已经提交了,A看到了B已提交的数据,

T2-A、T6-A:无数据,T8-A:有数据,多次读取结果不一样,

将隔离级别置为REPEATABLE-READ

重启mysql:

查看隔离级别:

先清空test1表数据:

按时间顺序在2个窗口中执行下面操作:

A窗口如下:

B窗口如下:

看一下:

T2-A、T6-A窗口:无数据,T5-B:有数据,A看不到B的数据,

T8-A:无数据,此时B已经提交了,A看不到B已提交的数据,A中3次读的结果一样都是没有数据的,

幻读只会在REPEATABLE-READ(可重复读)级别下出现,需要先把隔离级别改为可重复读。

将隔离级别置为REPEATABLE-READ

重启mysql:

查看隔离级别:

准备数据:

上面我们创建t_user表,name添加了唯一约束,表示name不能重复,否则报错。

按时间顺序在2个窗口中执行下面操作:

A窗口如下:

B窗口如下:

看一下:

A想插入数据路人甲Java,插入之前先查询了一下(T5时刻)该用户是否存在,发现不存在,然后在T7时刻执行插入,报错了,报数据已经存在了,因为T6时刻B已经插入了路人甲Java。

然后A有点郁闷,刚才查的时候不存在的,然后A不相信自己的眼睛,又去查一次(T8时刻),发现路人甲Java还是不存在的。

此时A心里想:数据明明不存在啊,为什么无法插入呢?这不是懵逼了么,A觉得如同发生了幻觉一样。

:事务A中先读取操作,事务B发起写入操作,事务A中的读取会导致事务B中的写入处于等待状态,直到A事务完成为止。

表示我开启一个事务,为了保证事务中不会出现上面说的问题(脏读、不可重复读、读已提交、幻读),那么我读取的时候,其他事务有修改数据的操作需要排队等待,等待我读取完成之后,他们才可以继续。

写读、写写也是互斥的,读写互斥类似。

这个类似于java中的java.util.concurrent.lock.ReentrantReadWriteLock类产生的效果。

下面演示读写互斥的效果。

将隔离级别置为SERIALIZABLE

重启mysql:

查看隔离级别:

先清空test1表数据:

按时间顺序在2个窗口中执行下面操作:

按时间顺序运行上面的命令,会发现T4-B这样会被阻塞,直到T5-A执行完毕。

上面这个演示的是读写互斥产生的效果,大家可以自己去写一下写读、写写互斥的效果。

读未提交( Read Uncommitted )

读已提交( Read Committed )

可重复读( Repeatable Read )

可串行化( Serializable )

扫一扫,分享内容

打赏作者

悬浮海

你的鼓励将是我创作的最大动力

您的余额不足,请更换扫码支付或

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。

2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

MySQL的基本使用——事务_王菜鸟的博客-CSDN博客_mysql事务怎么使用

关于触发器的复习题

事务处理在数据库开发过程中有着非常重要的作用,它可以保证在同一个事务中的操作具有同步性。

现实生活中,人们经常会进行转账操作,转账可以分为转人和转出两部分,只有这两个部分都完成才认为转账成功。在数据库中,这个过程是使用两条SQL语句来实现的,如果执行其中任意一条语句出现异常没有执行,则会导致两个账户的金额不同步,造成错误。为了防止上述情况的发生,就需要使用MySQL中的事务(Transaction)。

在MySQL中,事务就是针对数据库的一组操作,它可以由一条或多 条SQL语句组成,且每个SQL语句是相互依赖的。只要在程序执行过程中有一-条SQL语句执行失败或发生错误,则其他语句都不会执行。也就是说,事务的执行要么成功,要么就返回到事务开始前的状态,这就保证了同一事务操作的同步性和数据的完整性。

MySQL中的事务必须满足A、C、I、D这4个基本特性,具体如下。

(1)原子性(Atomicity)。原子性是指一个事务必须被视为一个不可分割的最小工作单元,只有事务中所有的数据库操作都执行成功,才算整个事务执行成功。事务中如果有任何一个SQL语句执行失败,已经执行成功的SQL语句也必须撤销,数据库的状态退回到执行事务前的状态。

(2)一致性(Consistency)。一致性是指在事务处理时,无论执行成功还是失败,都要保证数据库系统处于一致的状态,保证数据库系统不会返回到一个未处理的事务中。MySQL中的一致性主要由日志机制实现,通过日志记录数据库的所有变化,为事务恢复提供了跟踪记录。

(3)隔离性(Isolation)。隔离性是指当一个事务在执行时,不会受到其他事务的影响。保证了未完成的所有操作与数据库系统的隔离,直到事务完成为止,才能看到事务的执行结果。隔离性相关的技术有并发控制、可串行化、锁等。当多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

(4)持久性(Durability)。持久性是指事务一旦提交,其对数据库的修改就是永久性的。需要注意的是,事务的持久性不能做到百分百的持久,只能从事务本身的角度来保证永久性。而一些外部原因导致数据库发生故障,那么所有提交的数据可能都会丢失。

在默认情况下,用户执行的每一条SQL语句都会被当成单独的事务自动提交。如果要将一组SQL语句作为一个事务,则需要执行以下语句显示开启一个事务。

该语句的作用是让SQL语句不再自动提交,需要用户使用以下语句来进行手动提交,当事务提交后,操作的数据才会更改。

如果对提交的事务不满意,需要回滚,那么可以使用如下语句取消事务

使用步骤:

MySQL默认是自动提交模式,如果没有显示开启事务(

),每一条SQL语句都会自动提交(

)。如果想要控制自动提交,可以通过更改

变量来实现,将其值设为1表示开启自动提交,设为0表示关闭自动提交。

可以使用一条START TRANSACTION或begin语句来显式地启动一个事务。

语法格式:

COMMIT语句是提交语句,它使得自从事务开始以来所执行的所有数据修改成为数据库的永久部分,也标志一个事务的结束,其语法格式为:

ROLLBACK语句是撤销语句,它撤销事务所做的修改,并结束当前这个事务。

语法格式:

除了撤销整个事务,用户还可以使用ROLLBACK TO语句使事务回滚到某个点,在这之前需要使用SAVEPOINT语句来设置一个保存点。

语法格式为:

其中,

为保存点的名称。

语句会向已命名的保存点回滚一个事务。如果在保存点被设置后,当前事务对数据进行了更改,则这些更改会在回滚中被撤销,语法格式为:

当事务回滚到某个保存点后,在该保存点之后设置的保存点将被删除。

语句会从当前事务的一组保存点中删除已命名的保存点。不出现提交或回滚。如果保存点不存在,会出现错误。语法格式为:

事务的提交(COMMIT)和回滚(ROLLBACK)还有一些可选的字句,如:

在上述的选择中,

用于在当前事务结束时,立即启动一个新事务,并且新事务与刚结束的事务有相同的隔离级别;

用于在终止当前事务后,让服务器断开与客户端的连接。若添加

,则表示控制

完成。

由于数据库是一个多用户的共享资源,允许多线程并发访问,因此用户可以通过不同的线程执行不同的事务。为了保证这些事务直接不受影响,对事务设置隔离级是十分重要的。

对于隔离级别的查看,有几种不同的方式。如下:

基于ANSI/ISO SQL规范,MySQL提供了下面4种隔离级:

)、

)、

)、

)。

系统变量

中存储了事务的隔离级,可以使用SELECT获得当前会话隔离级的值

只有支持事务的存储引擎才可以定义一个隔离级。定义隔离级可以使用

语句。

语法格式:

是事务中最低的级别,在该级别下的事务可以读取到其他事务中未提交的数据,这种读取方式也被称为

。简而言之,脏读是指一个事务读取了另外一个事务未提交的数据。

是大多是数据库管理系统的默认隔离级,在该隔离级下只能读取其他事务已经提交的数据,避免了脏读数据的现象。但在该隔离级别下,会出现不可重复读(

)的问题。

是MySQL的默认事务隔离级,它解决了脏读和不可重复读的问题,确保了同一事务的多个实例在并发读取数据时,会看到同样的结果。

但在理论上,该隔离级会出现幻读(

)的现象。幻读又被称为虚读,是指在一个事务内两次查询中数据条数不一致。

是最高级别的隔离级,它在每个读的数据行上加锁,使之不会发生冲突,从而解决了脏读、不可重复读和幻读的问题。但是由于加锁可能导致超时和锁竞争现象,因此

也是性能最低的一种隔离级,除非为了数据的稳定性,需要强制减少并发的情况时,才会选择此种隔离级。

模拟网上支付

顾客A在线购买一款商品,价格为500.00元,采用网上银行转账的方式支付

假如顾客A银行卡的余额为2000.00元,且向卖家B支付购买商品费用500.00元,起始卖家B的账号金额10000.00元

创建数据库shop和创建表account并插入2条数据,如下图所示:

(1)A账户给B账户转账,如果正常,A账户的钱会减少,B账户钱会增加,但A账户钱不够或者B账户不可用,这时则需返回A账户的500元,达到账户总额的平衡;

(2)A给B转账成功后,B给C转账2倍金额(比如A->B 500元,B->C 1000元),如果B账户钱不够或者C账户不可用,这时候回滚到A->B刚转完的阶段。

要求:使用事务结合存储过程模拟以上过程

扫一扫,分享内容

打赏作者

王菜鸟

你的鼓励将是我创作的最大动力

您的余额不足,请更换扫码支付或

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。

2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

MySQL执行事务的语法和流程

关于事务的自动提交可阅读学习《

》一节。

BEGIN;

START TRANSACTION;

COMMIT;

ROLLBACK;

关注微信公众号「站长严长生」,在手机上阅读所有教程,随时随地都能学习。本公众号由

运营,每日更新,坚持原创,敢说真话,凡事有态度。

精美而实用的网站,分享优质编程教程,帮助有志青年。千锤百炼,只为大作;精益求精,处处斟酌;这种教程,看一眼就倾心。

Copyright ©2012-2021 biancheng.net,