@

为什么写这系列的文章

在日常的工作和开发中,接触最多的便是与数据库打交道,无论你使用什么框架进行开发都绕不开事务的管理. 在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. Qt 使用QGraphicsPixmapItem、QGraphicsScene、QMatrix 的QGraphicsView的显示,缩放

    .h QGraphicsScene *scene; QGraphicsPixmapItem *theFrame; QMatrix matrix; .cpp MainWindow::MainWindow ...

  2. ElasticSearch 本机可以访问,外网无法访问----问题解决

    问题:本机可以访问,外网无法访问 config/elasticsearch.yml network.host: 0.0.0.0 使用普通用户zuoys,重启es,报错如下: [1]: max file ...

  3. day54-mysql-库、表、数据操作

    . 什么是数据库 存储数据的仓库 . 什么数据: 大家所知道的都是数据.比如:你同学的名字,年龄,性别等等 . 数据库概念 .数据库服务器 .数据库管理系统 重点 .库 .表 .记录 .数据 参考画图 ...

  4. MFC的sendmessage和postmessage 以及sendmessagetimeout

    PostMessage只负责将消息放到消息队列中,不确定何时及是否处理,相当于异步操作,执行后马上返回SendMessage要等到受到消息处理的返回码(DWord类型)后才继续,相当于同步操作,一直在 ...

  5. MySQL允许某个IP网段从远程访问的方法

    grant select,insert,update,create on test.* to test@'192.168.8.%' identified by '123456';     允许增删改查 ...

  6. springboot多数据源+jta事务管理配置

    1.创建一个maven项目,导入相关配置: <?xml version="1.0" encoding="UTF-8"?> <project x ...

  7. 关联规则之FpGrowth算法

    Aprori算法利用频繁集的两个特性,过滤了很多无关的集合,效率提高不少,但是我们发现Apriori算法是一个候选消除算法,每一次消除都需要扫描一次所有数据记录,造成整个算法在面临大数据集时显得无能为 ...

  8. 3)Framework创建思路

  9. Python基本了解

    1. 计算机基础知识 CPU : 人类的大脑,运算处理问题 内存 : 临时储存数据,断点数据就会消失,存储数据快 硬盘 : 永久存储各种数据,相对于内存存储速度慢 操作系统 : 本质上是一个软件,用于 ...

  10. Qt QImage的浅拷贝与深拷贝

    首先简单说说什么是浅拷贝和深拷贝:浅拷贝就比如像引用类型,而深拷贝就比如值类型,即浅拷贝是共用一块内存的,而深拷贝是复制一份内容. 我们再来看看QImage类的几个构造函数: // 浅拷贝 QImag ...