事务回滚

高性能MySQL之事务

自闭症网瘾萝莉.ら 提交于 2020-03-08 12:05:01
原文: 高性能MySQL之事务 背景 当你手中抓住一件东西不放时,你只能拥有一件东西,如果你肯放手,你就有机会选择更多。与其在别人的生活里跑龙套,不如精彩做自己。人无所舍,必无所成。跌倒了,失去了,不要紧,爬起来继续风雨兼程,且歌且行。 一、概念 事务到底是什么东西呢?想必大家学习的时候也是对事务的概念很模糊的。接下来通过一个经典例子讲解事务。 银行在两个账户之间转账,从A账户转入B账户1000元,系统先减少A账户的1000元,然后再为B账号增加1000元。如果全部执行成功,数据库处于一致性;如果仅执行完A账户金额的修改,而没有增加B账户的金额,则数据库就处于不一致状态,这时就需要取消前面的操作。这过程中会有一系列的操作,比如余额查询,余额做加减法,更新余额等,这些操作必须保证是一个整体执行,要么全部成功,要么全部失败,不能让A账户钱扣了,但是中途某些操作失败了,导致B账户更新余额失败。这样用户就不乐意了,银行这不是坑我吗?因此简单来说,事务就是要保证一组数据库操作,要么全部成功,要么全部失败。在MySQL中,事务支持是在引擎层实现的。你现在知道,MySQL是一个支持多引擎的系统,但并不是所有的引擎都支持事务。比如MySQL原生的MyISAM引擎就不支持事务,这也是MyISAM被InnoDB取代的重要原因之一。 接下来会以InnoDB为例,抽丝剥茧MySQL在事务支持方面的特定实现

Python连接MySQL数据库之pymysql模块使用

依然范特西╮ 提交于 2020-03-07 08:23:59
Python连接MySQL数据库之pymysql模块使用 Python3连接MySQL 本文介绍Python3连接MySQL的第三方库--PyMySQL的基本使用。 PyMySQL介绍 PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb。 Django中也可以使用PyMySQL连接MySQL数据库。 PyMySQL安装 pip install pymysql 连接数据库 注意事项 在进行本文以下内容之前需要注意: 你有一个MySQL数据库,并且已经启动。 你有可以连接该数据库的用户名和密码 你有一个有权限操作的database 基本使用 # 导入pymysql模块 import pymysql # 连接database conn = pymysql.connect(host=“你的数据库地址”, user=“用户名”,password=“密码”,database=“数据库名”,charset=“utf8”) # 得到一个可以执行SQL语句的光标对象 cursor = conn.cursor() # 定义要执行的SQL语句 sql = """ CREATE TABLE USER1 ( id INT auto_increment PRIMARY KEY , name CHAR(10) NOT NULL UNIQUE

Transaction 事务回滚无效,常见原因!!!

梦想与她 提交于 2020-03-03 05:28:54
今天使用@Transcation注解的形式为serivce服务添加事物,但是无论如何都无法回滚! 在网上找了很多帖子,自己总结了一下. 开始说事务之前,不得不提一下java的异常类型: 分为checked异常和unchecked异常 checked异常:非系统原因造成的异常,比如需要Try - catch处理,或者throws抛出到上一层去,继承自java.lang.Exception(不包括java.lang.RuntimeException) unchecked异常:系统原因自己造成的异常,如空指针异常,类型转换异常等,不需要在系统中显示的捕获处理。继承自java.lang.RuntimeException 下面是注解形式的事物在Spring中的配置 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">

Spring事务失效

倖福魔咒の 提交于 2020-03-02 18:05:31
面试必备技能:JDK动态代理给Spring事务埋下的坑 一、场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1、场景A: 这里其实是分别执行了两个事物,执行的结果是两个方法都可以插入数据!如下: 2、场景B: 修改上述代码如下: Propagation.REQUIRES_NEW的含义表示:如果当前存在事务,则挂起当前事务并且开启一个新事物继续执行,新事物执行完毕之后,然后在缓刑之前挂起的事务,如果当前不存在事务的话,则开启一个新事物。 执行的结果是两个方法都可以插入数据!执行结果如下: 场景A和场景B都是正常的执行,期间没有发生任何的回滚,假如child()方法中出现了异常! 3、场景C 修改child()的代码如下所示,其他代码和场景B一样: 执行结果如下,会出现异常,并且数据都没有插入进去: 疑问1:场景C中child()抛出了异常,但是parent()没有抛出异常,按道理是不是应该parent()提交成功而child()回滚? 可能有的小伙伴要说了,child()抛出了异常在parent()没有进行捕获,造成了parent()也是抛出了异常了的!所以他们两个都会回滚! 4、场景D 按照上述小伙伴的疑问这个时候,如果对parent()方法修改

Spring声明式事务@Transactional 详解,事务隔离级别和传播行为

风流意气都作罢 提交于 2020-03-02 09:42:20
@Transactional注解支持9个属性的设置,这里只讲解其中使用较多的三个属性:readOnly、propagation、isolation。其中propagation属性用来枚举事务的传播行为,isolation用来设置事务隔离级别,readOnly进行读写事务控制。 @Service @Transactional(readOnly = true) public class AppTradeRec2Service extends BaseService { @Autowired private AppTradeRecDao appTradeRecDao; @Autowired private ConsInfoDao consInfoDao; @Transactional(readOnly = false) public void payCharge(TradeRec tradeRec) { User usr = UserUtils.getUser(); ConsInfo cons = consInfoDao.getByUser(usr.getId()); //修改交易记录 tradeRec.setPayBefore(cons.getAccountAmt()); tradeRec.setPayAfter(cons.getAccountAmt() - tradeRec

java异常之运行期异常和checked异常

*爱你&永不变心* 提交于 2020-03-02 08:28:35
运行期异常和checked异常的区别: Throwable 是所有 Java 程序中错误处理的父类 ,有两种资类: Error 和 Except io n 。 Error :表示由 JVM 所侦测到的无法预期的错误,由于这是属于 JVM 层次的严重错误 ,导致 JVM 无法继续执行,因此,这是不可捕捉到的,无法采取任何恢复的操作,顶多只能显示错误信息。 Except io n :表示可恢复的例外,这是可捕捉到的。 Java 提供了两类主要的异常 :runtime except io n 和 checked exception 。 checked 异常也就是我们经常遇到的 IO 异常,以及 SQL 异常都是这种异常。 对于这种异常, JAVA 编译器强制要求我们必需对出现的这些异常进行 catch 。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆 catch 块去处理可能的异常。 但是另外一种异常: runtime exception ,也称运行时异常,我们可以不处理。当出现这样的异常时,总是由虚拟机 接管。比如:我们从来没有人去处理过 NullPointerException 异常,它就是运行时异常,并且这种异常还是最常见的异常之一。 出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由 Thread.run() 抛出

浅谈Spring事务隔离级别

僤鯓⒐⒋嵵緔 提交于 2020-02-29 10:54:03
一、Propagation (事务的传播属性) Propagation :  key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用:PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。 PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。 1: PROPAGATION_REQUIRED 加入当前正要执行的事务不在另外一个事务里,那么就起一个新的事务 比如说,ServiceB.methodB的事务级别定义为PROPAGATION_REQUIRED, 那么由于执行ServiceA.methodA的时候, ServiceA.methodA已经起了事务,这时调用ServiceB.methodB,ServiceB.methodB看到自己已经运行在ServiceA

Spring 事务-04-隔离和传播-4-TransactionTemplate

一笑奈何 提交于 2020-02-27 03:01:43
1、用途 Spring的公共事务属性实现。默认情况下回滚运行时异常,但未被检查。 2、类图 3、类分析 import org.springframework.lang.Nullable; import org.springframework.transaction.interceptor.TransactionAttribute; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.util.StringUtils; /** * Spring的公共事务属性实现。 * 默认情况下回滚运行时异常,但未被检查。 */ @SuppressWarnings("serial") public class DefaultTransactionAttribute extends DefaultTransactionDefinition implements TransactionAttribute { @Nullable private String qualifier; @Nullable private String descriptor; /** * 使用默认设置创建一个新的DefaultTransactionAttribute。 *

面试官:分布式事务了解吗?你们是如何解决分布式事务问题的?

▼魔方 西西 提交于 2020-02-26 03:05:33
面试官心理分析 只要聊到你做了分布式系统,必问分布式事务,你对分布式事务一无所知的话,确实会很坑,你起码得知道有哪些方案,一般怎么来做,每个方案的优缺点是什么。 现在面试,分布式系统成了标配,而分布式系统带来的分布式事务也成了标配了。因为你做系统肯定要用事务吧,如果是分布式系统,肯定要用分布式事务吧。先不说你搞过没有,起码你得明白有哪几种方案,每种方案可能有啥坑?比如 TCC 方案的网络问题、XA 方案的一致性问题。 面试题剖析 分布式事务的实现主要有以下 5 种方案: XA 方案 TCC 方案 本地消息表 可靠消息最终一致性方案 最大努力通知方案 两阶段提交方案/XA方案 所谓的 XA 方案,即:两阶段提交,有一个事务管理器的概念,负责协调多个数据库(资源管理器)的事务,事务管理器先问问各个数据库你准备好了吗?如果每个数据库都回复 ok,那么就正式提交事务,在各个数据库上执行操作;如果任何其中一个数据库回答不 ok,那么就回滚事务。 这种分布式事务方案,比较适合单块应用里,跨多个库的分布式事务,而且因为严重依赖于数据库层面来搞定复杂的事务,效率很低,绝对不适合高并发的场景。如果要玩儿,那么基于 Spring + JTA 就可以搞定,自己随便搜个 demo 看看就知道了。 这个方案,我们很少用,一般来说某个系统内部如果出现跨多个库的这么一个操作,是不合规的。我可以给大家介绍一下,

对注解@Transactional的解读

送分小仙女□ 提交于 2020-02-25 22:19:30
在SpringBoot则非常简单,只需在业务层添加事务注解(@Transactional )即可快速开启事务。虽然事务很简单,但对于数据方面是需要谨慎对待的。 @Transactional注解用于两种场景: 标于类上:表示所有方法都进行事务处理 标于方法上:仅对该方法有效 一、事务传播行为 @Transactional(propagation=Propagation.REQUIRED) :如果有事务, 那么加入事务, 没有的话新建一个(默认情况下) @Transactional(propagation=Propagation.NOT_SUPPORTED) :容器不为这个方法开启事务 @Transactional(propagation=Propagation.REQUIRES_NEW) :不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务 @Transactional(propagation=Propagation.MANDATORY) :必须在一个已有的事务中执行,否则抛出异常 @Transactional(propagation=Propagation.NEVER) :必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反) @Transactional(propagation=Propagation