@

为什么写这系列的文章

在日常的工作和开发中,接触最多的便是与数据库打交道,无论你使用什么框架进行开发都绕不开事务的管理. 在Java开发中你可能会接触很多ORM框架,无论是Hibernate、MyBatis、还是Spring Jdbc 都会遇到事务的相关操作,再到中大型项目,你还会遇到单一数据源本地事务、多数据源本地事务、分布式事务、分布式多数据源事务等各种奇葩环境,数据的一致性也会面临各种挑战,在这时如何游刃有余的处理数据一致性就考验你对事务的理解,也正是这系列文章写作的真正原因.

由于我换工作原因,先后在峰鸟科技、人人网、国家电网待过一段时间,先后接触了不同的ORM框架

峰鸟科技
在这里由于SQL比较灵活,同时考虑到性能问题,这里直接使用的Spring JDBC,为了提高开发效率,我也开发了一个简单ORM框架,用来将javabean 和 数据库表信息进行关联,提供了简单的增删改查和分页功能,这时候也是我初步接触框架的开发,接触反射、代理等功能

人人网
在这里先后使用 Python 和 Java 进行开发,用过MyBatis、Django-orm、sqlalchemy、JPA、Jade等ORM框架。其中Jade是人人网自行开发的ORM框架,使用简单,支持条件化语句、支持多数据源切换和多数据源事务功能,相对MyBatis来说,使用方式和功能更加友好,强大。

国家电网
在这里主要使用的MyBaits,第一次看见Spring事务注解可以添加到类上而不是方法上,这也说明你懂的还是不多

通过不同的经历,也先后接触到了JDBC事务、Spring事务、Hibernate事务、MyBaits事务、多数据源事务、分布式事务的使用和解决方案,这里总结一下

事务概念

事务(Transaction):一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。

数据库事务(Database Transaction):是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。

ACID

  1. atomicity 原子性
    原子性:操作这些指令时,要么全部执行成功,要么全部不执行。只要其中一个指令执行失败,所有的指令都执行失败,数据进行回滚,回到执行指令前的数据状态。
  2. consistency 一致性
    一致性:事务的执行使数据从一个状态转换为另一个状态,但是对于整个数据的完整性保持稳定。
  3. isolation 隔离性
    隔离性:在该事务执行的过程中,无论发生的任何数据的改变都应该只存在于该事务之中,对外界不存在任何影响。只有在事务确定正确提交之后,才会显示该事务对数据的改变。其他事务才能获取到这些改变后的数据。
  4. durability 持久性
    持久性:当事务正确完成后,它对于数据的改变是永久性的。

并发事务导致的问题

在许多事务处理同一个数据时,如果没有采取有效的隔离机制,那么并发处理数据时,会带来一些的问题。

脏读(Dirty Read)

当一个事务读取另一个事务尚未提交的修改时,产生脏读。

同一事务内不是脏读。 一个事务开始读取了某行数据,但是另外一个事务已经更新了此数据但没有能够及时提交。这是相当危险的,因为很可能所有的操作都被回滚,也就是说读取出的数据其实是错误的。

非重复读(Nonrepeatable Read)

一个事务对同一行数据重复读取两次,但是却得到了不同的结果。同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读。

幻读(Phantom Reads)

事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询过程中有另外一个事务插入数据造成的。

当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。

丢失修改(Lost Update)

第一类:当两个事务更新相同的数据源,如果第一个事务被提交,第二个却被撤销,那么连同第一个事务做的更新也被撤销。

第二类:有两个并发事务同时读取同一行数据,然后其中一个对它进行修改提交,而另一个也进行了修改提交。这就会造成第一次写操作失效。

事务隔离

为了兼顾并发效率和异常控制,在标准SQL规范中,定义了4个事务隔离级别.

读未提交(Read Uncommitted)

直译就是"读未提交",意思就是即使一个更新语句没有提交,但是别的事务可以读到这个改变。

Read Uncommitted允许脏读。

读已提交(Read Committed)

直译就是"读提交",意思就是语句提交以后,即执行了 Commit 以后别的事务就能读到这个改变,只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别。

Read Commited 不允许脏读,但会出现非重复读。

可重复读(Repeatable Read):

直译就是"可以重复读",这是说在同一个事务里面先后执行同一个查询语句的时候,得到的结果是一样的。

Repeatable Read 不允许脏读,不允许非重复读,但是会出现幻象读。

串行读(Serializable)

直译就是"序列化",意思是说这个事务执行的时候不允许别的事务并发执行。完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞。

Serializable 不允许不一致现象的出现。

通过不同的隔离级别,可以防止一些并发事务问题,同时级别越高则相应性能越低,这个设置需要根据实际场景进行设置.

下一篇:MySQL数据库事务以及存储引擎
系列文章:
事务Transaction
Spring Cloud 分布式事务管理
Spring Cloud 分布式事务管理(二)2pc/3pc

事务Transaction的更多相关文章

  1. SQL Server 数据库的维护(三)__事务(transaction)和锁

    --维护数据库-- --事务(transaction)和锁-- --事务(transaction)-- --概述: 事务是指封装了一组T-SQL语句的单个逻辑单元.单元中的所有语句作为一个整体,在满足 ...

  2. JDBC中的事务-Transaction

    事务-Transaction 某些情况下我们希望对数据库的某一操作要么整体成功,要么整体失败,经典的例子就是支付宝提现.例如我们发起了支付宝到银行卡的100元提现申请,我们希望的结果是支付宝余额减少1 ...

  3. Spring事务Transaction配置的五种注入方式详解

    Spring事务Transaction配置的五种注入方式详解 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学 ...

  4. SQL Server中事务transaction如果没写在try catch中,就算中间语句报错还是会提交

    假如我们数据库中有两张表Person和Book Person表: CREATE TABLE [dbo].[Person]( ,) NOT NULL, ) NULL, ) NULL, [CreateTi ...

  5. FireDAC 下的 Sqlite [7] - 备份、优化、事务(Transaction)

    用 TFDSQLiteBackup 控件, 两三行代码即可完成 Sqlite 数据库的备份. procedure TForm1.Button1Click(Sender: TObject); begin ...

  6. 事务(Transaction)概念和特性

    http://baike.baidu.com/view/121511.htm 概念 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库 ...

  7. redis源码分析之事务Transaction(下)

    接着上一篇,这篇文章分析一下redis事务操作中multi,exec,discard三个核心命令. 原文地址:http://www.jianshu.com/p/e22615586595 看本篇文章前需 ...

  8. 数据库事务(Transaction)

    事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit). 事务四大特性(ACID): 原子性(Atomicity):个事务是一个不可分割的工作单位,事务中包括的 ...

  9. jdbc、事务(Transaction)、批处理 回顾

    论文写的头疼,回顾一下jdbc,换换脑子 传统的写法: 1.加载驱动类 class.forname("jdbc类的包结构"); 2.获得连接 Connection conn=Dri ...

随机推荐

  1. mysql only_full_group_by

    下载安装的是最新版的mysql5.7.x版本,默认是开启了 only_full_group_by 模式的,但开启这个模式后,原先的 group by 语句就报错,然后又把它移除了. 一旦开启 only ...

  2. hdu2896&&3065

    题:http://acm.hdu.edu.cn/showproblem.php?pid=2896 分析:ac自动机模板 注意细节,1.128个ascii码都要: 2.只要关键码含有只输出一个编号就行 ...

  3. 华为路由器AR1220E-S通过web页面不能登录

    问题原因:由于在WEB页面配置了“远程信任主机”,但是信任主机和路由器不在一个网段,导致所有IP都不能通过WEB页面管理路由器 解决方案:通过console口直接连接路由器,删除信任主机,此次咨询了华 ...

  4. springboot集成aop日志

    日常开发中假如是前后端完全分离,我们会习惯用浏览器去调用controller的接口来测试.这一个过程普通的日志功能会记录sql参数等一些基本信息.但是假如项目越来越庞大,我们的包越来越多,在维护项目和 ...

  5. 十四、linux-MySQL的数据库集群读写分离及高可用性、备份等

    一.数据库集群及高可用性 二.mysql实现读写分离 mysql实现读写分离有多种方式: 1)代码语言(php\python\java等)层面实现读写分离,找开发进行实现. 2)通过软件工具实现读写分 ...

  6. AdminSwagger2Configuration

    package org.linlinjava.litemall.admin.config; import org.springframework.context.annotation.Bean; im ...

  7. android 9.0 http无法访问问题

    在res/xml下新建network-security-config.xml <?xml version="1.0" encoding="utf-8"?& ...

  8. gpio 的配置

    1.时钟使能 B引脚RCC时钟脉冲启动.|(或)表示只要第三个为1就行. 也可以写为RCC_APB2ENR  | = 0X0008; 2.配置GPIO的输出模式以及速度 3 . 如果是 0号引脚:GP ...

  9. 非参数检验|Sign test|Wilcoxon signed rank test|Wilcoxon rank sum test|Bootstrapping

    非参数检验条件没有参数,因此就没有分布,利用数据等级之间的差距,依次赋值之后再用参数方法测试.将连续型变量转化为离散型变量,即顺序变量.与参数检验相比,正态分布较弱(p值有可能不显著,浪费信息,比如最 ...

  10. 使用dtree构建框架导航

    前言: 该例子就是个框架导航 , 左边包含dtree的框架,点击上面的节点右边框架显示 说明步骤: 1. 首先获得dtree  http://www.destroydrop.com/javascrip ...