数据库事务基本原理与分布式事务
1、JDBCAPI概论DriverManager: 解耦的设计,抽象工厂模式;Connection:和数据库建立连接的一份封装,底层就是Socket APIStatement:语句集,SQL解析器,解析SQL语法(协议,语言,语法)ResultSet:通过执行Sql获取的一个结果封装,结果在java中的体现形式(MAP + Cursor)Transaction:访问并更新数...
1、JDBC API概论
DriverManager: 解耦的设计,抽象工厂模式;
Connection:和数据库建立连接的一份封装,底层就是Socket API
Statement:语句集,SQL解析器,解析SQL语法(协议,语言,语法)
ResultSet:通过执行Sql获取的一个结果封装,结果在java中的体现形式(MAP + Cursor)
Transaction:访问并更新数据库中各种数据项的一个程序执行单元。
事务设计原理:每次数据库操作都允许后悔,有一个缓冲区操作:新建一张和目标表结构一样的临时表,将修改,删除,新增数据写入临时表,检查操作是否可行;当commit / roolback的时候才决定是否替换目标表;
select直接扫描表然后解析,返回结果,利用index提升查询性能;
2、什么是事务?
事务目的:就是用来确保操作数据的完整性与一致性;
事务特性:要达到恢复和并发控制基本单元,事务需要具备的特性;ACID
原子性:事务是一个整体,是密不可分的,具有原子的特性,要么都成功,要么都失败;
一致性:事务一旦开启,处理事务的这整个过程,数据满足总体状态不会变(质量守恒),讲究数据的准确性;
隔离性:事务与事务之间,是互不干扰的,相互之间不影响,目的是为了防止数据被破坏;锁
持久性:事务一旦提交commit,他的结果就应该具有持久性,保存在磁盘,不应该再次被同一事务进行破坏;
事务的隔离级别:要求事务必须在它处理完了之后其他事务才能处理相同的数据;开发过程中严格的遵循事务的隔离性,虽然保证了数据的准确性,但牺牲了整个项目的效率; 但是在实际开发中,要在数据准确性(空间)和反应性能(时间)上综合的权衡,“时空转换”;严格遵循隔离性不可取; 获得性能上准确性的问题如何解决?这可以通过隔离级别进行控制
可串行化(serializable):事务的最高隔离级别,绝对可以保证数据的准确性,其他隔离在不同程度上允许数据的不一致;实现原理接近于对数据加锁;
可重复读(Repeatable Read):使用最广泛的一种; 隔离级别仅次于上面的可串行化,但是它有一个问题,它会造成数据幻读问题,给操作者造成一种不应该有的幻觉;操作大量数据才会出现; 幻读就是当前事务不是独立执行的时候发生(两个事务需要同时对一张数据进行修改;);
例如:A操作将所有员工工资从3k增加到5K;然后返回所有人员信息;
B在这个批量删改和返回之间修改了其中一条的为2K,A就会读取到幻觉的数据;
读已提交(Read Committed):隔离级别仅次于可重复读,会造成不可重复读;不可重复度:是指数据库访问过程中,同一个事务范围内两次查询的结果不一致;
例如:在一个事务中,多次读取同一数据,在这个事务还没有结束的时候,
另外一个事务访问了这个数据,并做了修改;那第一个事务再次读取的数据就不一样了,这样对于数据库而言,不可重复读远比幻读来的容易,我们在工作中使用更多的是可重复读;
读未提交(Read Uncommitted):隔离级别最低的,开发中勿用,会造成脏读,事务在处理的时候,可以读取其它事务尚未提交的数据,来做开发; 脏读也叫无效数据读取,在系统中根据无效数据做出的操作是不是正确的; 程序流程:在事务嵌套操作中允许一个事务中去读取另一个事务尚未提交的值;总 结:如何保证数据准确性,以及如何保证系统灵活性,需要结合实际的业务场景和性能要求和并发请求情况综合权衡。
事务的传播:当有多个同时具有事务控制能力的Service的实现类方法互调的时候所形成的事务边界控制问题;在Spring框架中常见的事务边界控制(传播特性)有以下7种:
1、REQUERED:支持当前事务,如果当前没有事务,就新建一个事务----最为常见(CUD增删改的时候;) a()----b() a有事务就按a的事务,没有则新建一个b的事务,按照b的事务走; spring默认事务方式
2、SUPPORTS:支持当前事务,如果没有事务,就按照非事务方式执行,通常在查询的时候使用最为广泛
3、MANDATORY:支持前事务,如果没有事务,就抛出异常;
4、REQUERED_NEW:无论有没有事务,都新建一个新的事务,并且按照新的事务来执行,并将老事务挂起,老事务不影响新事务,新事物执行异常如果异常被捕获也不会影响新事务;
5、NOT-SUPPORTS:以非事务执行,如果当前有事务就将当前事务挂起; 例如:登录只有登录操作读取,没有事务操作
6、NEVER:以非事务方式执行,如果当前存在事务则抛出异常。
7、NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中; 如果没有活动事务,则按REQUERED属性执行; 使用了一个单独的事务,这个事务拥有多个可以回滚的保存点; 内部事务的回滚不会对外部事务造成影响,他只对DataSourceTransactionMannger事务管理器起效
在Spring框架中处理事务:
1、事务的使用方式:
一、编程式事务,将事务控制的代码嵌入到业务逻辑的方法中去管理事务的提交与回滚;通常在编程式事务中,必须在每一个业务操作的方法中都包含有额外的事务管理代码;
二、声明式事务,在企业应用开发中最为常见;将事务管理申明在配置文件中,采用AOP面向切面的思想动态管理业务层的事务,它将事务管理提到切面中,将事务代码从核心业务中分离出来,让程序员只需要关注于核心业务
2、spring事务框架结构
核心接口:PlatformTransactionMannger 提供方法:getTransaction() commit() rollack()
spring实现事务控制的逻辑:DataSource包装的Connection 是一个单例的,通过动态代理拿到该对象就可以进行操作;
分布式事务:
跨库事务的问题: 网络分区、通信异常、三态(未知状态)、节点故障;
CAP原理: 可用性 分区容错性 放弃一致性
BASE : 基本可用,软状态,最终一致性;
分布式事务解决方案:基于2阶段提交的TCC原理实现,
分布式事务框架:Fescar 、 GTS、 Hmily
更多推荐




所有评论(0)