@[TOC]java
在平常的工做和开发中,接触最多的即是与数据库打交道,不管你使用什么框架进行开发都绕不开事务的管理. 在Java开发中你可能会接触不少ORM框架,不管是Hibernate、MyBatis、仍是Spring Jdbc 都会遇到事务的相关操做,再到中大型项目,你还会遇到单一数据源本地事务、多数据源本地事务、分布式事务、分布式多数据源事务等各类奇葩环境,数据的一致性也会面临各类挑战,在这时如何游刃有余的处理数据一致性就考验你对事务的理解,也正是这系列文章写做的真正缘由.sql
因为我换工做缘由,前后在峰鸟科技、人人网、国家电网待过一段时间,前后接触了不一样的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)。atom
数据库事务(Database Transaction):是指做为单个逻辑工做单元执行的一系列操做,要么彻底地执行,要么彻底地不执行。 事务处理能够确保除非事务性单元内的全部操做都成功完成,不然不会永久更新面向数据的资源。经过将一组相关操做组合为一个要么所有成功要么所有失败的单元,能够简化错误恢复并使应用程序更加可靠。一个逻辑工做单元要成为事务,必须知足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工做单位,由DBMS中的事务管理子系统负责事务的处理。spa
原子性:操做这些指令时,要么所有执行成功,要么所有不执行。只要其中一个指令执行失败,全部的指令都执行失败,数据进行回滚,回到执行指令前的数据状态。.net
一致性:事务的执行使数据从一个状态转换为另外一个状态,可是对于整个数据的完整性保持稳定。
隔离性:在该事务执行的过程当中,不管发生的任何数据的改变都应该只存在于该事务之中,对外界不存在任何影响。只有在事务肯定正确提交以后,才会显示该事务对数据的改变。其余事务才能获取到这些改变后的数据。
持久性:当事务正确完成后,它对于数据的改变是永久性的。
在许多事务处理同一个数据时,若是没有采起有效的隔离机制,那么并发处理数据时,会带来一些的问题。
当一个事务读取另外一个事务还没有提交的修改时,产生脏读。
同一事务内不是脏读。 一个事务开始读取了某行数据,可是另一个事务已经更新了此数据但没有可以及时提交。这是至关危险的,由于极可能全部的操做都被回滚,也就是说读取出的数据实际上是错误的。
一个事务对同一行数据重复读取两次,可是却获得了不一样的结果。同一查询在同一事务中屡次进行,因为其余提交事务所作的修改或删除,每次返回不一样的结果集,此时发生非重复读。
事务在操做过程当中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据(这里并不要求两次查询的SQL语句相同)。这是由于在两次查询过程当中有另一个事务插入数据形成的。
当对某行执行插入或删除操做,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。
第一类:当两个事务更新相同的数据源,若是第一个事务被提交,第二个却被撤销,那么连同第一个事务作的更新也被撤销。
第二类:有两个并发事务同时读取同一行数据,而后其中一个对它进行修改提交,而另外一个也进行了修改提交。这就会形成第一次写操做失效。
为了兼顾并发效率和异常控制,在标准SQL规范中,定义了4个事务隔离级别.
直译就是"读未提交",意思就是即便一个更新语句没有提交,可是别的事务能够读到这个改变。
Read Uncommitted容许脏读。
直译就是"读提交",意思就是语句提交之后,即执行了 Commit 之后别的事务就能读到这个改变,只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别。
Read Commited 不容许脏读,但会出现非重复读。
直译就是"能够重复读",这是说在同一个事务里面前后执行同一个查询语句的时候,获得的结果是同样的。
Repeatable Read 不容许脏读,不容许非重复读,可是会出现幻象读。
直译就是"序列化",意思是说这个事务执行的时候不容许别的事务并发执行。彻底串行化的读,每次读都须要得到表级共享锁,读写相互都会阻塞。
Serializable 不容许不一致现象的出现。
经过不一样的隔离级别,能够防止一些并发事务问题,同时级别越高则相应性能越低,这个设置须要根据实际场景进行设置.
下一篇:MySQL数据库事务以及存储引擎
系列文章:
事务Transaction
Spring Cloud 分布式事务管理
Spring Cloud 分布式事务管理(二)2pc/3pc