`

(转)替代传统事务的并发建议

阅读更多

增删改查是大部分框架的功能,如果有两个并发请求修改同一个数据怎么办?或者插入本来应该是唯一却重复的数据怎么办?或者插入和修改有其他辅助动作比如保存到另外的表比如校订审计日志。

你会首先想到“事务”,事务确实能够让一组操作一起可靠安全执行,要么全部执行,要么一个也别想执行,如果有两个同时发生的并发事务怎么办?使用事务隔离级别,这是ACID中的定义,关系数据库内部机制中就是这么做的。

但是,如果使用隔离级别,比如可串行化serializable (以及可重复读),你的系统会变得很慢,依赖于不同关系数据库,同时发生的事务也许需要应用代码编码指定重试几次,这就很复杂,其他不是很严格的隔离级别则会带来更新丢失或幽灵phantom 读。

即使你正确地设置了合适隔离级别,你也能用代码正确处理了事务的失败错误情况,但是隔离并不能解决所有并发问题,比如应用级别的数据约束,也就是说,是一种复杂的业务逻辑约束或规则,很难使用数据库的表键约束来实现的;单纯使用数据库技术也不能解决重复插入的问题;更不能解决应用级别的并发问题;不能解决数据并发等问题。也许你试图通过获得数据库锁来解决这些问题,但是锁是可怕的,锁有写锁 读锁和排他锁,如何避免死锁?不是每个程序员能够有经验和锁打交道的。

双重提交问题是经典问题,它说明了不是所有问题都可以通过数据库方式单独解决的,双重提交很多人的解决办法是:使用一个token代表每个请求,并存储在数据库,使用数据库的唯一键约束,这样,重复记录就无法插入,这种问题使用API比较复杂,因为你得根据API的用户才能产生合适的token。另外,虽然你使用数据库唯一约束,但是还得在应用代码中进行检查,因为两行记录虽然键不同但是值相同还是可能被插入的。

大部分并发是运行在单机上,这可以使用语言的并发特性来确保执行的串行化,双重重复不可能发生,但是当你部署应用在几台机器以上,并发问题变得困难。

下面是不使用事务而使用并发的解决思路:
1.类似Hazelcast之类提供分布式锁,整个集群都遵循锁语义如同单机一样,但是适用场景不多。

2.使用消息队列– 将所有请求推入消息队列,队列会被单个异步worker处理,但是可能不适合业务上需要立即返回给用户的场景。

3. 使用Akka和其集群,能保证一个actor (可看成一个服务)一次只处理一个消息,但是因为akka完全改变了使用范式,难以使用和跟踪调试,而且和语言平台特点有关。

4.使用数据库的应用级别锁,比如关系数据库Postgre提供 advisory锁, MySQL也有类似的get_lock, 使用关系数据库作为分布式锁机制,锁是被应用管理,不需要表库做任何事,只要请求为entityType, entityId字段请求一个锁,保证没有其他应用线程只有在获得数据库锁的情况下才能执行应用中指定一段代码,相当于用数据库锁替代语言同步锁,,然后使用Spring的 @Before 之类AOP方式拦截服务的方法。

5.使用CRDT. 它是一种幂等的数据结构,不管操作其之上的操作顺序,最终都是同样的结果状态。但是完全幂等的操作在实际中也是很少碰到。

6.使用“insert-only”只追加模型. 像Datomic之类数据库内部使用这种模型,你可以在任何数据库中使用这种模型,只有新增追加,没有删除和更新,每次使用新的版本号插入新记录. 这样版本号的唯一性保证不会有重复记录。你不会丢失数据,相当于免费得到一个校订日志(banq注:实际是EventSourcing 事件流日志)

上面办法都是在不损失性能情况下如何串行化请求,包括了各种锁机制 队列和非堵塞I/O。

转自:http://www.jdon.com/48003

分享到:
评论

相关推荐

    44 1 MySQL数据库集群和高并发-Mycat分库配置

    2、支持事务、ACID、可以替代MySQL的加强版数据库 3、一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群 4、一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server 5、结合传统数据库和...

    stm:Go中的软件事务存储

    这是编写并发代码(通道和互斥锁)的标准方法的替代方法。 STM使得以原子方式执行任意复杂的操作变得容易。 与传统锁定相比,它的主要优势之一是STM事务是可组合的,而锁定功能则不是-组合将死锁或释放功能之间的...

    Mycat入门

    面向企业应用开发的大数据库集群支持事务、ACID、可以替代MySQL的加强版数据库一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQLServer结合传统...

    Mycat数据库中间件-其他

    MyCAT是一个强制数据库,可以替代MySQL,并支持事务和ACID。作为企业数据库的MySQL群集,MyCAT可以代替昂贵的Oracle群集。MyCAT还是一种新型的数据库,它看起来像是与内存缓存技术,NoSQL技术和HDFS大数据集成的SQL ...

    Mycat数据库中间件 v1.13

    MyCAT是一个强制数据库,可以替代MySQL,并支持事务和ACID。作为企业数据库的MySQL群集,MyCAT可以代替昂贵的Oracle群集。MyCAT还是一种新型的数据库,它看起来像是与内存缓存技术,NoSQL技术和HDFS大数据集成的SQL ...

    Mycat2数据库中间件-其他

    MyCAT是一个强制数据库,可以替代MySQL,并支持事务和ACID。作为企业数据库的MySQL群集,MyCAT可以代替昂贵的Oracle群集。MyCAT还是一种新型的数据库,它看起来像是与内存缓存技术,NoSQL技术和HDFS大数据集成的SQL ...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

     事务控制语言(Transactional Control Language,TCL),用于维护数据的一致性,包括COMMIT(提交事务)、ROLLBACK(回滚事务)和SAVEPOINT(设置保存点)3条语句 二、 Oracle的数据类型 类型 参数 描述 字符类型...

    javaSE代码实例

    第16章 多线程——Java中的并发协作 343 16.1 线程的基本知识 343 16.1.1 多线程编程的意义 343 16.1.2 定义自己的线程 344 16.1.3 创建线程对象 345 16.1.4 启动线程 347 16.1.5 同时使用多个线程 ...

    二十三种设计模式【PDF版】

    整体结构和一些主要职责(如数据库操作 事务跟踪 安全等),剩余的就是变化的东西,针对这个领域中具体应用产生的具体不同 的变化需求,而这些变化东西就是 J2EE 程序员所要做的。 由此可见,设计模式和 J2EE 在思想...

Global site tag (gtag.js) - Google Analytics