mysql事务

Innodb存储引擎

匿名 (未验证) 提交于 2019-12-03 00:30:01
Innodb存储引擎 一次写入操作是一次事务,innodb 首先把事务数据写入到缓存池 Buffer Pool 和重做日志redo log中,然后就可以提交事务,响应客户端了。之后 innodb 再将新事务的数据异步地写入磁盘,真正存储起来。 Innodb主要是通过事务日志实现ACID特性 事务日志包括:重做日志redo和回滚日志undo Redo记录的是已经全部完成的事务,就是执行了提交的事务,记录文件是ib_logfile0 ib_logfile1 Undo记录的是已部分完成并且写入硬盘的未完成的事务,默认情况下回滚日志是记录下表空间中的(共享表空间或者独享表空间) 一般情况下,mysql在崩溃之后,重启服务,innodb通过回滚日志undo将所有已完成并写入磁盘的未完成事务进行回滚,然后redo中的事务全部重新执行一遍即可恢复数据,但是随着redo的量增加,每次从redo的第一条开始恢复就会浪费长的时间,所以引入了checkpoint机制 1.缓存池 buffer pool 数据的读写需要经过缓存(缓存在buffer pool 即在内存中) 数据以整页(16K)位单位读取到缓存中 缓存中的数据以LRU策略换出(最少使用策略) IO效率高,性能好(不用IO) 读操作: 数据是以页为存储单位,在缓冲池中缓存了很多数据页,当第一次读取时首先将页从磁盘读取到缓存池中

悲观乐观锁

匿名 (未验证) 提交于 2019-12-03 00:26:01
1. 悲观锁 悲观锁介绍(百科): 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。 使用场景举例 :以MySQL InnoDB为例 商品goods表中有一个字段status,status为1代表商品未被下单,status为2代表商品已经被下单,那么我们对某个商品下单时必须确保该商品status为1。假设商品的id为1。 1如果不采用锁,那么操作方法如下: //1.查询出商品信息 select status from t_goods where id=1; //2.根据商品信息生成订单 insert into t_orders (id,goods_id) values (null,1); //3.修改商品status为2 update t_goods set status=2; 上面这种场景在高并发访问的情况下很可能会出现问题。 前面已经提到,只有当goods status为1时才能对该商品下单,上面第一步操作中,查询出来的商品status为1。但是当我们执行第三步Update操作的时候

Spring基于注解配置事务的属性

匿名 (未验证) 提交于 2019-12-03 00:22:01
在Spring中,事务属性描述了事务策略如何应用到方法上,事务属性包含5个方面: ① 传播行为 ② 隔离级别 ③ 回滚策略 ④ 超时时间 ⑤ 是否只读 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如,方法可能继续在现有的事务中允许,也可能开启一个新事务,并在自己的事务中运行。 事务的传播行为可以由传播属性指定,Spring定义了7种类型的传播行为。其中最常用的是 REQUIRED 和 REQUIRES_NEW 。 事务的传播属性可以在 @Transactional 注解的 propagation 属性中定义。 举个例子: /** * 使用 @Transactional 指定事务方法 */ @Service ( "bookShopService" ) public class BookShopServiceImpl implements BookShopService { /** * 1. 添加事务注解@Transactional。 * 2. 使用 propagation 指定事务的传播行为, * 即当前事务方法被另外一个事务方法调用时,如何使用事务: * 是使用调用方法的事务,还是开启一个新事务(使用自己的事务)。 * 3. propagation: * ① 默认值是 Propagation.REQUIRED, 即使用调用方法的事务。 * ② 可以指定为

springboot2.0事务未生效

匿名 (未验证) 提交于 2019-12-03 00:22:01
配置加了 @EnableTransactionManagement 方法上加了 @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class) 不起作用。 原因:Springboot2.0后,依然是使用jpa、Hibernate来操作mysql,发现Hibernate默认创建的表是myisam引擎,而不是innodb不起作用,myisam引擎是不支持事务的 CREATE TABLE `user` ( `id` int(11) NOT NULL, `username` varchar(255) DEFAULT NULL, `password` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 添加下面的方言即可修改为innodb spring: jpa: database: mysql show-sql: true hibernate: ddl-auto: update naming: physical-strategy: org.springframework.boot

事务

匿名 (未验证) 提交于 2019-12-03 00:16:01
什么是事务 : 举例 : 张三李四 进行 转账的操作 事务的四大特性(ACID): 并发访问问题----由隔离性引起 : 1.脏读: 2.不可重复读: 3.幻觉读: 事务的隔离级别: read uncommited:读取未提交的数据:哪个问题都不能解决。 read commited:读取已提交的数据:可以解决脏读,oracle默认的级别。 repeatable read:重读读取: 可以解决脏读和不可重复读,mysql默认的级别。 serializable:串行化: 可以解决脏读、不可重复读、幻觉读,相当于锁表。 java事务 主要有两种:jdbc事务(本地事务),jta (java tranaction api)事务(分布式事务) 一、JDBC事务操作: jdbc默认的是自动事务,执行slq语句,executeUpdate() ---- 每执行一次executeUpdate方法 代表 事务自动提交。 jdbc的API手动事务: (1) 开启事务:conn.setAutoCommit(false) //关闭自动提交,开启收到提交; (2) 提交事务:coon.commit(); (3) 回滚事务:coon.rollback(); 注意:控制事务的connnection必须是同一个 执行sql的connection与开启事务的connnection必须是同一个才能对事务进行控制 /

mysql事务的隔离级别

南笙酒味 提交于 2019-12-03 00:14:28
mysql事务的隔离级别 查看当前数据库的隔离级别: select @@tx_isolation; 默认的隔离级别为:可重复度(REPEATABLE-READ) 设置当前会话的隔离级别: set tx_isolation='<隔离级别>' 读未提交----read-uncommitted 当多个会话同时操作同一张表,其中某一个会话M尝试去读取表中的数据时,它会直接读取到其他会话开启事务后对表的内容造成修改后的但事务尚未提交的内容。当事务发生回滚,会话M再去查询,会出现与此之前不同的数据,造成脏读。 会话A开启事务,往表中修改了数据,但事务还未结束。此时会话B想要查询这个表的数据,查到的内容是刚刚会话A修改后的内容。若会话A在会话B刚刚查询之后选择回滚了事务,会话B再去查询,会跟之前查询到的内容不一样。 读已提交----read-committed 跟上面的读未提交的相反,当前的会话只会读到其他会话结束后的表数据,无论其他会话在自己的事务中做了啥修改,只要为结束当前的会话,其他的会话都无法读取到会话未结束前的修改。 可重复读----repeatable-read 会话M开始事务去查询的同时,其他多个会话在对会话M查询的内容做修改,无论其他会话结束与否,会话M的事务只要没有结束,会话M去查询的内容始终与会话M开启事务时查询到的内容一致。当会话M的事务结束后,会话M再去查询

子查询|视图|事务

匿名 (未验证) 提交于 2019-12-03 00:13:02
# 增:insert into 表 select子查询 # 删:delete from 表 条件是select子查询(表不能与delete表相同) # 查:select 字段 from 表 条件是select子查询 # 改:update 表 set 字段=值 条件是select子查询(表不能与update表相同) # 数据来源:在单表emp下 # 子查询:将一条查询sql的结果作为另一条sql的条件 # 思考:每个部门最高薪资的那个人所有信息 # 子查询的sql select dep, max(salary) from emp group by dep; # 子查询 - 查 select * from emp where (dep, salary) in (select dep, max(salary) from emp group by dep); # 将子查询转换为一张表 # 创建一个存子查询数据的一张表 create table t1(dep_name varchar(64), max_salary decimal(5,2)); # 子查询 - 增 insert into t1 select dep, max(salary) from emp group by dep; # 需求 select name, dep_name, salary from emp join t1

X/Open DTP模型与XA协议之我见

匿名 (未验证) 提交于 2019-12-03 00:05:01
X/Open DTP(Distributed Transaction Process)是一个分布式事务模型。这个模型主要使用了两段提交(2PC - Two-Phase-Commit)来保证分布式事务的完整性。 参考博文1中给除了基于DTP模型的分布式事务大致的流程: 而且,博客中提到:XA 协议描述了 TM 与 RM 之间的接口,允许多个资源在同一分布式事务中访问。XA 协议使用 2PC(Two Phase Commit,两阶段提交)原子提交协议来保证分布式事务原子性。两阶段提交是指将提交过程分为两个阶段,即准备阶段(投票阶段)和提交阶段(执行阶段): 看到这里我不禁心生疑惑: 图中的步骤3和5存在的意义是什么呢 ?假如 将步骤3合并到步骤7中,将步骤5和并到步骤8中会不会有什么问题呢 ?因为在参考书5中介绍的两阶段提交,就是在准备阶段进行业务操作,在第二阶段进行提交或回滚。 带着这个疑惑,我又找到了参考博客2。博客中提到使用X/Open DTP编程的一般方式为: 1. 配置TM,通过TM或者RM提供的方式,把RM注册到TM。可以理解为给TM注册RM作为数据源。一个TM可以注册多个RM。 2. AP从TM获取资源管理器的代理(例如:使用JTA接口,从TM管理的上下文中,获取出这个TM所管理的RM的JDBC连接或JMS连接) 3. AP向TM发起一个全局事务。这时,TM会通知各个RM

Hibernate入门这一篇就够了

匿名 (未验证) 提交于 2019-12-02 23:57:01
Hibernate入门这一篇就够了 本博文主要讲解 介绍Hibernate框架,ORM的概念和Hibernate入门 ,相信你们看了就会使用Hibernate了! Hibernate是一种ORM框架,全称为 Object_Relative DateBase-Mapping ,在Java对象与关系数据库之间 建立某种映射,以实现直接存取Java对象 ! 既然Hibernate是关于Java对象和关系数据库之间的联系的话,也就是 我们MVC中的数据持久层->在编写程序中的DAO层... 首先,我们来回顾一下我们在DAO层写程序的历程吧: 在DAO层操作XML,将数据封装到XML文件上,读写XML文件数据实现CRUD 在DAO层使用原生JDBC连接数据库,实现CRUD 嫌弃JDBC的Connection\Statement\ResultSet等对象太繁琐,使用对原生JDBC的封装组件-->DbUtils组件 我们来看看使用DbUtils之后,程序的代码是怎么样的: public class CategoryDAOImpl implements zhongfucheng.dao.CategoryDao{ @Override publicvoidaddCategory(Category category) { QueryRunner queryRunner = new QueryRunner

系统学习消息队列分享(五) 如何利用事务消息实现分布式事务?

匿名 (未验证) 提交于 2019-12-02 23:56:01
一说起事务,你可能自然会联想到数据库。的确,我们日常使用事务的场景,绝大部分都是在操作数据库的时候。像 MySQL、Oracle 这些主流的关系型数据库,也都提供了完整的事务实现。那消息队列为什么也需要事务呢? 其实很多场景下,我们“发消息”这个过程,目的往往是通知另外一个系统或者模块去更新数据,消息队列中的“事务”,主要解决的是消息生产者和消息消费者的数据一致性问题。 依然拿我们熟悉的电商来举个例子。一般来说,用户在电商 APP 上购物时,先把商品加到购物车里,然后几件商品一起下单,最后支付,完成购物流程,就可以愉快地等待收货了。 这个过程中有一个需要用到消息队列的步骤,订单系统创建订单后,发消息给购物车系统,将已下单的商品从购物车中删除。因为从购物车删除已下单商品这个步骤,并不是用户下单支付这个主要流程中必需的步骤,使用消息队列来异步清理购物车是更加合理的设计。 对于订单系统来说,它创建订单的过程中实际上执行了 2 个步骤的操作: 在订单库中插入一条订单数据,创建订单; 发消息给消息队列,消息的内容就是刚刚创建的订单。 购物车系统订阅相应的主题,接收订单创建的消息,然后清理购物车,在购物车中删除订单中的商品。 在分布式系统中,上面提到的这些步骤,任何一个步骤都有可能失败,如果不做任何处理,那就有可能出现订单数据与购物车数据不一致的情况,比如说: 创建了订单,没有清理购物车;