mysql数据库insert update delete操作数据是否是原子性操作
多个线程并发的对同一个资源进行访问,经常会造成
原子性,这里借用了物理学上的语义。历史上一度认为原子是不可再分割的。原子操作是不可分割的,在执行完毕不会被任何其它任务或事件中断。 多个线程并发的对同一个资源进行访问,经常会造成严重的后果,比如各线程之间相互覆盖共享数据,造成被访问数据处于不一致状态等等。 代码的原子性,与代码的长度不是同一个问题,比如说 count++; 1 1 看上去只是一行代码,一个操作,但是,这个操作不是原子性,因为这行代码并不会作为一个不可分割的操作来执行。 这一行代码,包含了三个独立的操作:读取count的值,将值加1,将计算结果写入count。 由于count++这行代码不是原子性的,当多个线程访问count++这行代码时,count的值可能就不是我们期望的结果了。 在Linux内核中,提供了一组实现原子操作的接口。Java.util.current.atomic包中包含了一些原子变量类,这些原子变量类能够便捷帮助程序开发者实现在数值和对象引用上的原子状态转换。 单个变量的原子性得到保障之后,还有一种情况经常遇见,既要保障一系列操作的原子性,将共享数据想象成一个只接受2P的妓女,如果我们开发了一个线程去嫖她,前戏进入高潮,这一系列过程,我肯定不想被其他线程(嫖客)横插一屌。程序当中,一些共享的数据,如果并发的访问,会造成程序错误。那怎样才能取保只有一个执行线程在访问共享的数据呢?——–各种锁机制。 锁,将共享数据挡在身后。在一个指定的时间内,只能有一个执行线程访问共享数据。 乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。那么我们如何实现乐观锁呢,一般来说有以下2种方式: 1.使用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式。何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据。用下面的一张图来说明: 如上图所示,如果更新操作顺序执行,则数据的版本(version)依次递增,不会产生冲突。但是如果发生有不同的业务操作对同一版本的数据进行修改,那么,先提交的操作(图中B)会把数据version更新为2,当A在B之后提交更新时发现数据的version已经被修改了,那么A的更新操作会失败。 2.乐观锁定的第二种实现方式和第一种差不多数据库更新操作,同样是在需要乐观锁控制的table中增加一个字段,名称无所谓,字段类型使用时间戳(timestamp), 和上面的version类似,也是在更新提交的时候检查当前数据库中数据的时间戳和自己更新前取到的时间戳进行对比,如果一致则OK,否则就是版本冲突。 (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |