`
liangguanhui
  • 浏览: 112897 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

自斟自饮——3. 原子性操作

阅读更多



我们都知道,数据库的ACID,其中A就是Atom,原子性,也就是要么全部做完,要么全部不做。但你对这个原子性了解有多少呢?实际上,原子性应该分两个级别,语句级,以及事务级。

事务级的比较容易理解,begin work,然后开干,到最后commit还是rollback,看具体需要,这个就是事务级的原子性。这一点对于所有的现代数据库都应该没有任何异议的,我们理解起来也应该没有任何异议。

至于语句级的原子性,就是指在没有显式地启动事务。实际上,所有的数据库,除了oracle,默认都是自动提交,也就是,执行完一条普通SQL后,不需要显式地执行commit(除非你显式地begin work)。

下面的testing,是指没有显式地启动事务的前提下进行的。


(1)这个是Insert的情况

create temp table tmp_test1 (tid integer primary key); 
create temp table tmp_test2 (tid integer);

insert into tmp_test1 values (1); 

insert into tmp_test2 values (2); 
insert into tmp_test2 values (3); 
insert into tmp_test2 values (1); 
insert into tmp_test2 values (4);


目前为止,数据准备完毕。然后,

insert into tmp_test1 select * from tmp_test2;


这条SQL语句当然会出错,因为存在tid = 1的重复主键,但如果出错之后,你再去查tmp_test1,你觉得结果会是什么?还是只有一条数据?还是有三条?还是一条都没有?估计不会有四条吧?你应该不会以为是五条都齐全吧?你觉得在 Informix、oracle、PostgreSQL、MySQL的结果是不是一样的?


(2)这个是Update

先准备数据:

create temp table tmp_test1 (
   tid   integer primary key,
   tint  integer,
   tname char(10)
);

insert into tmp_test1 values (1, 0,  'A'); 
insert into tmp_test1 values (2, 1,  'A'); 
insert into tmp_test1 values (3, 5,  'A'); 
insert into tmp_test1 values (4, 10, 'A');
insert into tmp_test1 values (5, 5,  'B');


然后执行这一句update:

update tmp_test1 set tid = tint where tname = 'A';


这条SQL语句当然会出错,因为存在tid = 5的重复主键(第三条record),但如果出错之后,你再去查tmp_test1,你觉得这个表的内容会变成什么样子?你觉得在 Informix、oracle、PostgreSQL、MySQL的结果是不是一样的?


(3)下面这个是Java的

准备一个数据表,注意,这个不是临时表:

create table test1 (tid integer primary key); 


然后用Java插入数据(注意:我这里忽略了Connection的生成过程,作为资深的你应该可以明白):

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Test1 {
   
   public static void test1(Connection conn) throws SQLException {
       conn.setAutoCommit(true);    // 这里设置为自动提交
       String sql = "insert into test1 values (?)";
       PreparedStatement ps = conn.prepareStatement(sql);

       ps.setInt(1, 1);
       ps.addBatch();

       ps.setInt(1, 2);
       ps.addBatch();

       ps.setInt(1, 3);
       ps.addBatch();

       ps.setInt(1, 1);    // 注意:这里会出现唯一键,但还没有报异常
       ps.addBatch();

       ps.executeBatch();    // 注意:这里才会出现SQL异常
       ps.close();
   }
   
}


很明显,有两个1,所以重复主键,但你觉得在执行excuteBatch并出现异常后,数据库的表test1的数据是怎样的?你觉得在 Informix、oracle、PostgreSQL、MySQL的结果是不是一样的?




































实际上各个数据库对于事务级别的原子性的支持应该是大体一样的,就是要么全部完成,要么全部不完成。

但对于语句级别的原子性,不同的数据库会有不同的对待。对于Oracle、PostgreSQL、MySQL,它会保证语句级别也是原子性的。具体来说,对于一个SQL语句,要么全部完成,要么全部不完成,打个比方,我们在这两个数据库中用一条SQL把100w条数据插进一个表,当到了最后一条系统发现有问题,它不仅仅会不插入这一有问题的record,也会把之前的999999条数据都rollback回去。至于其他的数据库,SQL Server暂时没试过,Informix被证明不是语句级别的原子性。(SQL Server在默认情况下估计多半不是)

这里我附上mysql、pgsql和Informix的结果。

MySQL




PostgreSQL




Informix





甚至,这里有个更加极端的地方。我们都知道trigger这个东西,触发器。有一类触发器是在插入一条数据之前触发,(before insert)。假如,存在一个表格test1,它有一个before insert的trigger,会把一条log insert到另外一个表格test1_log里面。正常情况下,我们每插进一条数据到test1,应该就会有一条数据插进到test1_log。但假如insert到test1的数据有问题,例如唯一性重复,那之前在before insert trigger插进到test1_log的数据,到底还在不在?

这个问题其实也是语句级别原子性的问题,按照Oracle和PostgreSQL的标准,它会保证语句级别的原子性,所以test1_log的那条数据会被rollback。而informix还没有机会试过,但从之前的测试看应该是不会rollback的。

最后提提JDBC的executeBatch,实际上这个操作对于数据库来说也就是把SQL一句一句来执行,当然可能已经做了相应的优化(例如把“硬解释”的结果存储下来,以后每次都只进行“软解释”)。如果中途出错,很明显,哪一句出问题,那一句之前的都执行成功,之后都不成功,而那一句就要似乎数据库对于语句原子性的支持。

虽然上面说的都是自动提交的情况,但,即使是在显示地启动事务的情况下也一样会遇到这个问题。对待这种问题,Oracle和PostgreSQL会以一种类似潜套事务(Nested Transaction)的形式处理,就是说那条出错的语句会整条rollback,但对于这个事务是没有影响的。
  • 大小: 64.4 KB
  • 大小: 4.8 KB
  • 大小: 1.4 KB
  • 大小: 1.5 KB
2
2
分享到:
评论

相关推荐

    long和double类型操作的非原子性探究(csdn)————程序.pdf

    在多线程环境下,原子操作是非常关键的,因为它可以保证数据的一致性和完整性。根据《深入 Java 虚拟机》的描述,Java中的`int`和其他不超过32位的基本类型的操作默认是原子性的,这意味着在单个处理器上,这些类型...

    学习笔记——sql.zip

    事务(TRANSACTION)用于确保数据库操作的原子性、一致性、隔离性和持久性,是数据库系统中的重要概念。最后,SQL还有触发器(TRIGGER),可以在特定事件(如INSERT、UPDATE或DELETE)发生时自动执行指定的操作。 ...

    简单租房项目学习——mysql.zip

    4. **事务处理**:在租房过程中,涉及的数据库操作通常需要保证原子性、一致性、隔离性和持久性(ACID特性)。例如,当用户支付租金并签订合同时,支付和签约这两个操作应作为一个事务处理,以防止因网络问题导致...

    惊人的能量——核能.pptx

    3. **原子核的能量** 原子核的质量并不等于组成核的质子和中子质量之和,这一差异被称为质量亏损。根据爱因斯坦的质能方程E=mc²,这部分质量亏损可以转化为巨大的能量,即原子核的结合能。例如,氕核(氢核)的...

    mysql存储引擎(csdn)————程序.pdf

    InnoDB的最大特点是它支持事务处理(ACID属性:原子性、一致性、隔离性、持久性),这意味着在多用户环境下,InnoDB可以保证数据的一致性和完整性。此外,InnoDB还支持行级锁定,这在处理大量并发更新操作时非常有利...

    毕业设计-mysql-基于Servlet银行柜员操作系统的设计和实现——程序.zip

    MySQL作为数据库,其ACID(原子性、一致性、隔离性、持久性)特性满足了银行交易对数据一致性的严格要求。 【压缩包子文件的文件名称】"4.毕业设计-mysql-基于Servlet银行柜员操作系统的设计和实现——程序"表明...

    生命活动的主要承担者——蛋白质.ppt

    标题中的“生命活动的主要承担者——蛋白质.ppt”指出,蛋白质在生物体内具有至关重要的角色。本内容详细阐述了蛋白质的结构、功能及其多样性。 蛋白质是细胞中含量丰富的有机物,占细胞鲜重的7%~10%,干重的比例更...

    java多线程学习笔记02(csdn)————程序.pdf

    而volatile只能修饰变量,无法保证整个代码块的原子性。但synchronized可以确保在释放锁之前,所有修改过的变量都可见,而volatile则没有这个保证。 Java 1.5引入的Lock接口扩展了同步机制,提供了更灵活的控制。...

    Redisson分布式锁学习总结:RedissonMultiLock 如何同时锁住N个资源(csdn)————程序.p.pdf

    这在处理复杂的并发场景时非常有用,比如在电商系统中同时锁定订单、库存和商品资源,确保这些操作的原子性。`RedissonMultiLock` 的实现原理相当直观,它实际上是对多个 `RedissonLock` 对象的封装,通过循环调用每...

    java+sql实现mysql数据表的数据结转(csdn)————程序.pdf

    1. **数据计数**:通过集成Redis,利用其原子性操作`incr`命令来实时统计`emax_timer_request`表中的数据记录数。每当有新的记录插入时,会调用`incr`方法增加计数值。当计数值达到200,000时,即触发数据结转。 2. ...

    MongoDB官网翻译(卷七)——事务.docx

    2. **多文档事务**:用于跨多个文档、集合、数据库或分片的原子性操作,确保数据的一致性。 ### 事务的ACID属性 - **原子性(Atomicity)**:所有操作要么全部成功,要么全部失败,不存在部分完成的状态。 - **...

    分布式事务 Seata AT 模式-Spring Cloud微服务案例(二)(csdn)————程序.pdf

    通过代理数据库操作,Seata确保了跨服务操作的一致性,从而实现了分布式环境下的原子性。通过上述配置和代码实现,我们可以构建一个完整的微服务示例,展示Seata如何在实际场景中解决分布式事务问题。

    15、喂——出来.ppt

    《15、喂——出来》这篇微型科幻小说是由日本现代科幻小说家星新一创作的,以其独特的构思和丰富的想象力闻名。文体上,微型科幻小说的特点在于它篇幅短小,融合了科学事实、预见和想象,描绘了未来世界的生活和技术...

    java互联网架构技术点+中大型项目实战(一)(csdn)————程序.pdf

    理解JMM有助于解决并发编程中的可见性、有序性和原子性问题。重点掌握volatile、final关键字的作用,了解happens-before原则,以及线程间的内存屏障。此外,还需理解内存泄漏和垃圾回收机制,确保程序的内存效率。 ...

    Redis高频面试笔记:基础+缓存雪崩+哨兵+集群+Reids场景设计(csdn)————程序.pdf

    - AOF(Append Only File):记录每次写操作的日志,确保数据安全性,但恢复速度较慢。 - 优缺点:RDB适合大数据量、对恢复时间要求不高的场景;AOF适合数据安全性要求高,允许少量数据丢失的场景。 3. **Redis ...

    第二节生物体中的有机化合物——蛋白质.doc

    【描述】: 这份文档详细介绍了高中生物课程中的重点和难点——蛋白质,包括氨基酸的结构、蛋白质的合成与结构多样性,以及其功能。 【标签】: 精品文档 **详细知识点:** 1. **氨基酸的结构**: 氨基酸是蛋白质的...

    一轮复习生命活动主要承担者——蛋白质.ppt

    【生命活动的主要承担者——蛋白质】是生物学中的重要概念,主要涵盖了两个主要的考点:蛋白质的结构和功能。 **考点一:组成蛋白质的氨基酸及其种类** 蛋白质的基本组成单位是氨基酸。氨基酸具有共同的核心结构,...

    网站开发中数据库的管理者——MySQL.pdf

    MySQL作为关系型数据库,遵循ACID(原子性、一致性、隔离性和持久性)原则,确保数据处理的准确性和可靠性。它支持SQL(Structured Query Language),这是一种统一、简洁且功能强大的语言,用于执行数据定义、查询...

    新一代CPU测试软件——Sciencemark.pdf

    3. Primordia 复数涓试:该测试项主要测试处理器对元素原子周暖的电子运算轨迹,通过对元素原子的电子运算轨迹进行测试,可以了解处理器对元素原子的电子运算能力。 Sciencemark 软件的使用非常简单,只需将软件...

Global site tag (gtag.js) - Google Analytics