分布式事务处理方案

首先,谢谢各位大神的指点。结合工作中遇到的问题和目前我了解到的分布式处理方案来简单谈谈。

1.事务的特性

  事务必须满足传统事务的ACID特性,即原子性,一致性,分离性和持久性。

  原子性:即最小单位的原子,要不全部成功,要不全部失败。

  一致性:。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少(百度百科)。个人理解:在数据库中的表现就是完整性约束没有被破坏。

  隔离性:事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据(百度百科)。个人理解:多个事务不应该影响其它事务运行效果。在数据库中是通过加锁和阻塞来保证事务之间不同等级的隔离性。不同的隔离级别是通过加不同的锁,造成阻塞来实现的。值得一提的是:完全的隔离性是不现实的,完全的隔离性要求数据库同一时间只执行一条事务,这样会严重影响性能。

  持久性:事务完成以后,持久的的保存在数据库,不会回滚。

2.本地事务

  本地事务,基本都是依赖数据库,在同一个数据库内,用数据库本身带的事务来保持事务。操作简单,这里就不说了。

3.分布式事务的出现

  随时,数据量的增加,单台数据库,或者简单的主从架构已经没法适应数据量的发展了。这个时候,可能需要做业务的服务化,那靠数据库本身已经做不了事务了。

  定义:分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上.

4.分布式事务解决方案

  4.1 两阶段提交协议

  定义:所谓的两阶段提交协议主要是分为2个阶段。第一阶段:准备阶段(投票阶段)和第二阶段:提交阶段(执行阶段)

  

通过以上4步完成了一个消息事务。对于以上的4个步骤,每个步骤都可能产生错误,下面一一分析:

  • 步骤一出错,则整个事务失败,不会执行A的本地操作
  • 步骤二出错,则整个事务失败,不会执行A的本地操作
  • 步骤三出错,这时候需要回滚预备消息,怎么回滚?答案是A系统实现一个消息中间件的回调接口,消息中间件会去不断执行回调接口,检查A事务执行是否执行成功,如果失败则回滚预备消息
  • 步骤四出错,这时候A的本地事务是成功的,消息中间件能够检查到A执行成功了,消息中间件可以自己对消息进行提交,从而完成整个消息事务

  4.1.1消息的保存

  如果仔细观察生活的话,生活的很多场景已经给了我们提示。
  比如在北京很有名的姚记炒肝点了炒肝并付了钱后,他们并不会直接把你点的炒肝给你,往往是给你一张小票,然后让你拿着小票到出货区排队去取。
  为什么他们要将付钱和取货两个动作分开呢?原因很多,其中一个很重要的原因是为了使他们接待能力增强(并发量更高)。

  还是回到我们的问题,只要这张小票在,你最终是能拿到炒肝的。同理转账服务也是如此,当用户A账户扣除1万后,
  我们只要生成一个凭证(消息)即可,这个凭证(消息)上写着“让用户B账户增加 1万”,只要这个凭证(消息)能可靠保存,
  我们最终是可以拿着这个凭证(消息)让用户B账户增加1万的,即我们能依靠这个凭证(消息)完成最终一致性。

    

  •   与业务耦合的模式。即,发送消息和执行本地事务在一个事务中,还是利用数据库本身的事务来保存数据,只是把后期消息的处理拆出来了,这个方案与业务耦合度太高,扩展性,等等都不太好,但是胜在简单。
  •   与业务解耦的模式。为了不与业务耦合,使架构更加的优雅,减少诱发其他问题。建议是使用解耦的模式。

  1)用户A在扣款事务提交之前,向实时消息服务请求发送消息,实时消息服务只记录消息数据,而不真正发送,只有消息发送成功后才会提交事务;

  2)当用户A扣款事务被提交成功后,向实时消息服务确认发送。只有在得到确认发送指令后,实时消息服务才真正发送该消息;

  3)当用户A扣款事务提交失败回滚后,向实时消息服务取消发送。在得到取消发送指令后,该消息将不会被发送;

  4)对于那些未确认的消息或者取消的消息,需要有一个消息状态确认系统定时去用户A系统查询这个消息的状态并进行更新。为什么需要这一步骤,
举个例子:假设在第2步用户A扣款事务被成功提交后,系统挂了,此时消息状态并未被更新为“确认发送”,从而导致消息不能被发送。

  优点:消息数据独立存储,降低业务系统与消息系统间的耦合;

  缺点:一次消息发送需要两次请求;业务处理服务需要实现消息状态回查接口。

  4.1.2 重复性提交问题

  其实,就是我们说的幂等性问题,即:任意多次执行所产生的影响均与一次执行的影响相同。

  解决方法很简单,在用户B这边增加消息应用状态表(message_apply),通俗来说就是个账本,用于记录消息的消费情况,每次来一个消息,
 在真正执行之前,先去消息应用状态表中查询一遍,如果找到说明是重复消息,丢弃即可,如果没找到才执行,同时插入到消息应用状态表(本地事务)。

  

时间: 2024-10-05 10:10:17

分布式事务处理方案的相关文章

分布式事务处理方案,微服事务处理方案

微服事务处理方案(分布式事务处理方案) 1. 什么是事务由一组操作构成的可靠. 独立的工作单元.事务具有以下特点:?Atomicity(原子性)?Consistency(一致性)?Isolation(隔离性)?Durability(持久性) 2.事务的一致性单体应用可以在数据库的事物管理器中获得强一致性,这种本地事物可靠简单.而在微服或者SOA的场景下,我们的本地事物就不作用了.对于分布式系统 Google 提出 CAP定理 ,分布式的事物只能同时拥有以下三项中的两个:?Consistency(

基于Solr和Zookeeper的分布式搜索方案的配置

1.1 什么是SolrCloud SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud.当一个系统的索引数据量少的时候是不需要使用SolrCloud的,当索引量很大,搜索请求并发很高,这时需要使用SolrCloud来满足这些需求. SolrCloud是基于Solr和Zookeeper的分布式搜索方案,它的主要思想是使用Zookeeper作为集群的配置信息中心. 它有几个特色功能: 1)集中式的配置信息 2)自动容错

分布式事务处理学习报告

1.什么是事务? 事务通俗说就是一个事情分为多个步骤完成: 比如: 2.事务的ACID四大属性: 原子性(Atomicity):意为:即一事务的操作要么全部执行,要么全部不执行.当事务非正常终止时,其中间结果将被取消. 一致性(Consistence):指的是保证数据在变化中只存在一个完整状态.比如修改一个人的信息(姓名,性别,年龄),在更新过程中发生错误,则所做的修改要么全没了,要么全保留. 隔离性(Isolation):一个未完成事务不能在提交前就把其中间结果提供给其它事务使用. 持久性(D

ORA-02049: 超时: 分布式事务处理等待锁诊断

正式环境有两个数据库A和B,在A库上建的dblink,业务是要将A库中的一些表,通过dblink更新到B库中去,更新的时候总是报错:ORA-02049: 超时: 分布式事务处理等待超时. 之前我写过一篇blog:ORA-02049: 超时: 分布式事务处理等待锁模拟,大致的意思是通过A更新B中的数据时,由于B库中的数据有锁,一直都不释放,导致通过A更新报错. 诊断如下: 在B库上执行,找到产生锁的会话 select s.owner, s.object_name, l.SID, l.TYPE, l

可扩容分布式session方案

分布式session有以下几种方案: 1. 基于nfs(net filesystem)的session共享 将共享服务器目录mount各服务器的本地session目录,session读写受共享服务器io限制,不能满足高并发. 2. 基于关系数据库的session共享 这种方案普遍使用.使用关系数据库存储session数据,对于mysql数据库,建议使用heap引擎. 这种方案性能取决于数据库的性能,在高并发下容易造成表锁(虽然可以采用行锁的存储引擎,性能会下降),并且需要自己实现session过

Memcached常规应用与分布式部署方案

1.Memcached常规应用 $mc = new Memcache(); $mc->conncet('127.0.0.1', 11211); $sql = sprintf("SELECT * FROM users WHERE uid = %d", $_GET['uid']); $key = md5($sql); //检测结果是否已经被缓存 if( ! $data = $mc->get($key)){ //没有缓存则直接从数据库读取 mysql_conncet('local

【转】错误: ORA-01591: 锁被未决分布式事务处理 7.2.428982 持有--解决方案

SQL 错误: ORA-01591: 锁被未决分布式事务处理 7.2.428982 持有 01591. 00000 -  "lock held by in-doubt distributed transaction %s" *Cause:    Trying to access resource that is locked by a dead two-phase commit transaction that is in prepared state. *Action:   DBA

.NET简谈事务、分布式事务处理

在本人的 " .NET简谈事务本质论"一文中我们从整体上了解了事务模型,在我们脑子里能有一个全局的事务处理结构,消除对数据库事务的依赖理解,重新认识事务编程模型. 今天这篇文章我们将使用.NET C#来进行事务性编程,从浅显.简单的本地事务开始,也就是我们用的最多的ADO.NET事务处理,然后我们逐渐扩大事务处理范围,包括对分布式事务处理的使用,多线程事务处理的使用. 数据库事务处理 数据库事务处理我们基本都很熟悉了,begin Transaction --end Transactio

分布式搜索方案选型

cnblogs - 分布式搜索方案选型