数据库事务

Mysql死锁

若如初见. 提交于 2020-01-08 16:11:01
mark下自己近期在电商开发中遇到的一个问题-数据库死锁及其排查过程。 先抛一个业务报错日志做为这次梳理的开始 上图是我接收到的错误报警,SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction,错误信息显示我们业务中有一条数据库操作遇到了死锁情况。接下来就开始我们的追查之旅。 1.执行“show engine innodb status”获取INNODB引擎当前信息( show engine innodb status 详细介绍 ) ------------------------ LATEST DETECTED DEADLOCK ------------------------ 2017-01-04 09:25:17 7f553477d700 *** (1) TRANSACTION: TRANSACTION 124378994, ACTIVE 0.007 sec starting index read mysql tables in use 1, locked 1 LOCK WAIT 4 lock struct(s), heap size 1184, 8 row lock(s), undo log entries

事务隔离级别

余生长醉 提交于 2020-01-08 16:10:48
1.1 未提交读 未提交读(READ_UNCOMMITTED)是最低的隔离级别,其含义是允许一个事物读取另一个事物没提交的数据。优点在于并发能力高,适合那些对数据一致性没有要求而追求高并发的场景,最大缺点是出现脏读。 @Transactional(isolation = Isolation.READ_UNCOMMITTED) 例子讲解: T3时刻,因为采用未提交读,所以事务2可以读取事务1未提交的库存数据为1,这里当它扣减库存后则数据为0,然后它提交了事务,库存就变为了0 。,而事务1在T5时刻回滚事务,因为第一类丢失更新已经被克服,所以它不会将库存回滚到2,那么最后的结果就变为了0,这样就出现了错误。 1.2 读写提交 读写提交(READ_COMMITTED),一个事务只能读取另外一个事务已提交的数据,不能读取未提交的数据。该级别克服了脏读,但不可重复读。 @Transactional(isolation = Isolation.READ_COMMITTED) 案例讲解: 1.3 可重复读 可重复读(REPEATABLE_READ),目标是克服读写提交中出现的不可重复读的现象,但会出现幻读。 1 @Transactional(isolation = Isolation.REPEATABLE_READ) 案例讲解: 1.4 串行化 串行化(SERIALIZABLE)

Spring事务原理

做~自己de王妃 提交于 2020-01-08 13:45:45
//相当于开启事务 //当我们execute的时候,就和服务端建立链接    dataSource.getConnection().createStatement(); //事务的回滚 dataSource.getConnection().rollback(); //默认的话是自动提交,所有的事务操作框架都会把autoCommit改成false,否则的话无法手动干预 dataSource.getConnection().setAutoCommit(false); //只读事务 dataSource.getConnection().setReadOnly(true); //事务的提交 dataSource.getConnection().commit(); 1、数据库操作,都会通过事务来管理 ACID,最大的问题,解决数据一致性的问题,能量守恒 分布式:分布式事务处理瞬时一致性,通常说的是最终的一致性(异步核对,主流的方式就通过日志) 事务的操作流程:事务只是一种思想,该如何用技术实现 像一般操作的Connection(接口)类,这个类是java客户端和数据库事务通信的桥梁,也就是一个包装类,就是一个TCP链接,底层就是socket 但java自己不实现,只是提供这个封装,提供这个JDK,让其他相关数据库厂商自己实现,所以我们要单独导入类似Mysql的jar包

Mysql 事务

巧了我就是萌 提交于 2020-01-08 06:08:41
事务的概念 事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行。 事务是一个不可分割的工作巡逻单元,在数据库系统上执行并发操作时,事务时最小的控制单元 适用于多用户同时操作的数据库系统的场景,如银行、保险公司及证券公司交易系统等等 通过事务的整体性以保证数据的一致性 事务的ACID特点 原子性(Atomicity) 事务是一个完整的操作,事务的各元素是不可分的(原子的) 事务中的所有元素必须作为一个整体提交或回滚 如果事务中的任何元素失败,则整个事务将失败 一致性(Consistency) 当事务完成时,数据必须处于一致状态:在事务开始之前,数据库中存储的数据处于一致状态;在正在进行的事务时,数据可能处于不一致的状态;当事务成功完成时,数据必须再次回到已知的一致状态 隔离性(Isolation) 对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务 修改数据的事务可以在另一个使用相同数据的事务开始之前访问这些数据,或者在另一个使用相同数据的事务结束之后访问这些数据 持久性(Durability 事务持久性不管系统是否发生故障,事务处理的结果都是永久的 一旦事务被提交,事务的效果被永久地保留在数据库中 事务的操作

数据事务四种隔离机制和七种传播行为

眉间皱痕 提交于 2020-01-08 05:46:46
数据事务四种隔离机制和七种传播行为 一、隔离级别: 数据库事务的隔离级别有4个,由低到高依次为 Read uncommitted、 Read committed、 Repeatable read、 Serializable,这四个级别可以逐个解决 脏读、 不可重复读、 幻读这几类问题。 1. ISOLATION_READ_UNCOMMITTED:这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。 这种隔离级别会产生脏读,不可重复读和幻像读。 2. ISOLATION_READ_COMMITTED:保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据 3. ISOLATION_REPEATABLE_READ:这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。 它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。 4. ISOLATION_SERIALIZABLE:这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。 除了防止脏读,不可重复读外,还避免了幻像读。 我们使用 test 数据库,新建 tx 表:---MySQL数据库 第1级别:Read Uncommitted(读取未提交内容) (1)所有事务都可以看到其他未提交事务的执行结果 (2

数据库事务的四种隔离机制和七种传播行为

不问归期 提交于 2020-01-08 03:59:52
MySQL数据库为我们提供的四种隔离级别:(依次解决脏读、不可重复读、幻读)   ① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。   ② Repeatable read (可重复读):可避免脏读、不可重复读的发生。(Mysql默认的方式)   ③ Read committed (读已提交):可避免脏读的发生。(Oracle默认的方式)   ④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。(INNODB内部机制) 数据库事务正常执行的四个特性: ACID属性: 原子性(atomicity):即不可分割,事务要么全部被执行,要么全部不执行 一致性(consistency):事务的执行使得数据库从一种正确状态转换成另外一种正确状态 隔离性(isolation):在事务正确提交之前,不允许把事务对该数据的改变提供给任何其他事务 持久性(durability):事务正确提交之后,其结果将永远保存在数据库之中,即使在事务提交之后有了其他故障,事务的处理结果也会得到保存 并发下事务产生的问题: 1、脏读:事务A读到了事务B还没有提交的数据; 2、不可重复读:在一个事务里面读取了两次某个数据,读出来的数据不一致; 3、幻读:在一个事务里面的操作中发现了未被操作的数据。 幻读,需要应用使用加锁读来保证

读写分离死锁解决方案、事务发布死锁解决方案、发布订阅死锁解决方案

怎甘沉沦 提交于 2020-01-07 20:50:29
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 前言: 由于网站访问压力的问题,综合分析各种因素后结合实际情况,采用数据库读写分离模式来解决当前问题。实际方案中采用“事务发布”模式实现主数据库和只读数据库的同步,其中:     发布服务器1台:sql2008,推送订阅模式     订阅服务器2台:sql2008 问题: 以上方案后实施后,数据同步正常,但从日志中发现了死锁情况。错误提示如:事务(进程 ID *)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。 查询一些资料后,确定是数据同步的同时资源被锁,同时用户访问页面请求,导致死锁产生,按照事务优先级,应用程序产生死锁。 解决方法: 找到大致思路后,查询了一些资料,大部分资料显示是死锁如何产生,如果跟踪日志,然后根据日志优化查询等方向,尝试一些方案后死锁减少,但并没有彻底解决,最后转换思路,从项目实际情况来看,主要是资讯信息的查询,对查询结果的安全性要求相对不高,所以可以接受“脏”数据的情况,在某种情况下又能提升查询的性能,于是在一些查询频繁和数据量比较大的几个表的select语句中加入with(nolock),死锁问题彻底解决。 建议: 处理一个数据库死锁的异常时候,其中一个建议就是使用 NOLOCK 或者 READPAST,对于非银行等严格要求事务的行业

【msql】关于redo 和 undo log

不打扰是莪最后的温柔 提交于 2020-01-07 20:14:29
InnoDB 有两块非常重要的日志,一个是undo log,另外一个是redo log,前者用来保证事务的原子性以及InnoDB的MVCC,后者用来保证事务的持久性。和大多数关系型数据库一样,InnoDB记录了对数据文件的物理更改,并保证总是日志先行,也就是所谓的WAL(Write Ahead Log),即在持久化数据文件前,保证之前的redo日志已经写到磁盘 一、概念 1、Innodb Crash Recovery 这是InnoDB引擎的一个特点,当故障发生,重新启服务后,会自动完成恢复操作,将数据库恢复到之前一个正常状态(不需要重做所有的日志,只需要执行上次刷入点之后的日志,这个点就叫做Checkpoint)恢复过程有两步 第一步:检查redo日志,将之前完成并提交的事务全部重做; 第二步:将undo日志中,未完成提交的事务,全部取消 2、LSN LSN(log sequence number) 用于记录日志序号,它是一个不断递增的 unsigned long long 类型整数。 在 InnoDB 的日志系统中,LSN 无处不在,它既用于表示修改脏页时的日志序号,也用于记录checkpoint,通过LSN,可以具体的定位到其在redo log文件中的位置。 LSN 用字节偏移量来表示。每个page有LSN,redo log也有LSN,Checkpoint也有LSN

分布式事务

孤街醉人 提交于 2020-01-07 20:12:05
前置知识 事务: 事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元,组成事务的所有操作只有在所有操作均能正常执行的情况下方能提交,只要其中任意一个执行失败,将导致整个事务的回滚。简单来说就是提供一种”要么什么都不做,要不全都做“的机制。 本地事务: 当事务是由资源管理器本地管理时被称为本地事务。本地事务的有点是支持严格的 ACID 特性,高效,可靠,状态可以只在资源管理器中维护,而且应用编程模型简单。但是本地事务不具备分布式事务的处理能力,隔离的最小单位受限于资源管理器。MySql 的 InnoDB 通过日志(Redo 和 Undo)和锁来保证事务。 全局事务: 当事务由全局事务管理器进行全局管理时成为全局事务,事务管理器负责管理全局事务状态和参与的资源,协同资源的一直提交回滚。 刚性事务和柔性事务 刚性事务:遵循 ACID 原则,强一致性,典型的例子就是数据库事务。 柔性事务:尊循 BASE 理论,最终一致性,允许在一定时间内,不同节点的数据不一致,但要求最终一致性。 分布式知识 CAP 分布式系统在设计时只能在一致性,可用性和分区容错性中满足两种,无法兼顾三种。 C: 在分布式环境中,一致性是指数据在多个副本之间是否能够保持一致的特性。在一致性的要求下,当一个系统在数据一致的状态下执行更新操作后,应该保证系统的数据仍然处于一致的状态。 A:

PostgreSQL 匿名自治事务补丁(翻译)

和自甴很熟 提交于 2020-01-07 19:12:16
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 原文链接 author Gilles Darold 2016-09-08 译者: 小次郎@飞象 8月19日我在 以前的帖子 中提到的 PostgreSQL 匿名自主事务的两个等价实现(使用不同的方法) 8月31日,Peter Eisentraut 提交了 补丁 ,实现了类似Oracle 的语法注解(AUTONOMOUS_TRANSACTION) 让我们看看它是如何使用的 这是一个打了语法补丁的PostgreSQL函数, 其中使用了自主匿名事务: 它将记录独立于数据库主线事务运行,并且不关心主线事务的最终结果。 CREATE OR REPLACE FUNCTION log_action_atx ( username text, event_date timestamp, msg text ) RETURNS VOID AS $body$ DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN START TRANSACTION; INSERT INTO table_tracking VALUES (nextval('log_seq'), username, event_date, msg); COMMIT; END; $body$ LANGUAGE plpgsql; CREATE