增删改查是大部分框架的功能,如果有两个并发请求修改同一个数据怎么办?或者插入本来应该是唯一却重复的数据怎么办?或者插入和修改有其他辅助动作比如保存到另外的表比如校订审计日志。
你会首先想到“事务”,事务确实能够让一组操作一起可靠安全执行,要么全部执行,要么一个也别想执行,如果有两个同时发生的并发事务怎么办?使用事务隔离级别,这是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
相关推荐
Disruptor是一种高性能的并发数据交换框架,由Martin Thompson、Dave Farley、Michael Barker、Patricia Gee和Andrew Stewart共同开发,主要用于替代传统的有界队列。这个框架的诞生源于LMAX公司在构建高性能金融...
Disruptor是由LMAX公司开发的一种创新的并发编程解决方案,旨在替代传统的有界队列,以实现极低延迟和高吞吐量的数据交换。该方案由Martin Thompson、Dave Farley、Micheal Barker、Patricia Gee和Andrew Stewart...
2、支持事务、ACID、可以替代MySQL的加强版数据库 3、一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群 4、一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server 5、结合传统数据库和...
LCN(Local Capable Notifier)是一个专门为Spring Boot和Dubbo设计的轻量级...但需要注意的是,任何分布式事务方案都不能完全替代对业务逻辑的精心设计,因此在实际应用中,应结合业务场景,选择最适合的事务策略。
此外,还有一些优化技术,如乐观锁定和多版本并发控制(MVCC),它们在某些场景下可以替代传统的悲观锁定,提高系统的并发性能。 总之,理解并掌握数据库锁定对于开发高效且可靠的数据库应用至关重要。它涉及到事务...
与传统事务管理方法相比,HBase_SI的最大创新之处在于使用两个全局队列来替代传统的两阶段提交协议,以此来控制事务的提交过程。这种方式能够有效地降低事务处理的复杂度,并提高系统的整体性能。 #### 三、HBase_...
不同于传统的数据库存储,状态对象通常驻留在应用服务器的内存中,这样可以极大地提高数据访问速度和应用响应时间。状态对象可以是任何类型的对象,如POJOs(Plain Old Java Objects),它们可以包含业务逻辑和数据...
MVCC(多版本并发控制)技术是数据库管理系统中用来提供并发访问数据库以及实现事务性内存的一种并发控制方法。MVCC技术允许读操作和写操作同时进行,而不互相阻塞,解决了在并发环境下读写操作之间的冲突问题,提供...
从本地事务到分布式事务,再到引入各种新技术模式和框架设施,这些改变都是为了更好地应对分布式环境下复杂的数据一致性和并发控制挑战。尽管如此,分布式事务处理仍然是一个充满挑战的领域,未来还需要不断探索新的...
传统的集中式架构由于无法满足横向扩展和快速响应业务变化的需求,逐渐被分布式架构所替代。分布式架构以其高并发、高可用、高性能、弹性扩展的特点,成为金融机构优化IT基础设施的关键。 一、金融机构全面布局...
TiDB的核心特点是高度兼容MySQL协议,这使得它可以无缝地替代传统的单机MySQL数据库,为大数据量、高并发的业务场景提供解决方案。 **MySQL协议兼容性** TiDB的一个关键特性是其对MySQL协议的深度兼容。这意味着...
OLTP,即在线事务处理(Online Transaction Processing),是一种用于处理事务型数据的技术,特别适用于高并发、实时的数据输入、查询和更新场景。在本文档中,OLTP通过"Looking Glass"的比喻,探讨了其架构和性能...
XML配置是最传统的,但现在逐渐被注解和Java配置替代,它们更加简洁且易于维护。 4. **事务管理**:事务管理是保证数据一致性和完整性的关键。Spring提供了两种事务管理方式:编程式事务管理和声明式事务管理。编程...
【银行开放平台OLTP数据库转型方案】主要针对的是传统银行IT架构面临的挑战,如处理能力有限、业务连续性要求提高、软件开发周期长、运行成本高等问题。为了解决这些问题,银行正在寻求从集中式的OLTP(Online ...
这种方式使得在Java应用中管理事务变得更加简洁高效,避免了传统XML配置带来的复杂性。以下是一些关键知识点: 1. **Spring框架**:Spring是一个开源的Java平台,它为构建企业级应用提供了全面的基础设施。其核心...
然而,Lardis可能没有实现Redis的持久化、复制、事务等高级特性,因为这些特性在无锁并发环境下实现起来较为复杂。通过对比Lardis与Redis的实现,我们可以更好地理解哪些特性在无锁并发中是必要的,哪些可以简化或...
为此,文章提出了一种名为SQLite-CC(Copy Cache)的新方法,该方法在NVM中维护一个拷贝缓存,同时管理事务执行,以减少I/O开销并提高并发性。 SQLite-CC引入了一个额外的管理器来协调事务,通过在cache中标记页面...
在高并发环境中,系统时间的准确获取是许多关键操作的基础,如事务处理、计时器、日志记录等。然而,传统的Java方法`System.currentTimeMillis()`在面对大量并发请求时可能会出现性能瓶颈。本文将深入探讨这个问题,...