我们都知道,数据库的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
分享到:
相关推荐
在多线程环境下,原子操作是非常关键的,因为它可以保证数据的一致性和完整性。根据《深入 Java 虚拟机》的描述,Java中的`int`和其他不超过32位的基本类型的操作默认是原子性的,这意味着在单个处理器上,这些类型...
事务(TRANSACTION)用于确保数据库操作的原子性、一致性、隔离性和持久性,是数据库系统中的重要概念。最后,SQL还有触发器(TRIGGER),可以在特定事件(如INSERT、UPDATE或DELETE)发生时自动执行指定的操作。 ...
4. **事务处理**:在租房过程中,涉及的数据库操作通常需要保证原子性、一致性、隔离性和持久性(ACID特性)。例如,当用户支付租金并签订合同时,支付和签约这两个操作应作为一个事务处理,以防止因网络问题导致...
3. **原子核的能量** 原子核的质量并不等于组成核的质子和中子质量之和,这一差异被称为质量亏损。根据爱因斯坦的质能方程E=mc²,这部分质量亏损可以转化为巨大的能量,即原子核的结合能。例如,氕核(氢核)的...
InnoDB的最大特点是它支持事务处理(ACID属性:原子性、一致性、隔离性、持久性),这意味着在多用户环境下,InnoDB可以保证数据的一致性和完整性。此外,InnoDB还支持行级锁定,这在处理大量并发更新操作时非常有利...
MySQL作为数据库,其ACID(原子性、一致性、隔离性、持久性)特性满足了银行交易对数据一致性的严格要求。 【压缩包子文件的文件名称】"4.毕业设计-mysql-基于Servlet银行柜员操作系统的设计和实现——程序"表明...
标题中的“生命活动的主要承担者——蛋白质.ppt”指出,蛋白质在生物体内具有至关重要的角色。本内容详细阐述了蛋白质的结构、功能及其多样性。 蛋白质是细胞中含量丰富的有机物,占细胞鲜重的7%~10%,干重的比例更...
而volatile只能修饰变量,无法保证整个代码块的原子性。但synchronized可以确保在释放锁之前,所有修改过的变量都可见,而volatile则没有这个保证。 Java 1.5引入的Lock接口扩展了同步机制,提供了更灵活的控制。...
这在处理复杂的并发场景时非常有用,比如在电商系统中同时锁定订单、库存和商品资源,确保这些操作的原子性。`RedissonMultiLock` 的实现原理相当直观,它实际上是对多个 `RedissonLock` 对象的封装,通过循环调用每...
1. **数据计数**:通过集成Redis,利用其原子性操作`incr`命令来实时统计`emax_timer_request`表中的数据记录数。每当有新的记录插入时,会调用`incr`方法增加计数值。当计数值达到200,000时,即触发数据结转。 2. ...
2. **多文档事务**:用于跨多个文档、集合、数据库或分片的原子性操作,确保数据的一致性。 ### 事务的ACID属性 - **原子性(Atomicity)**:所有操作要么全部成功,要么全部失败,不存在部分完成的状态。 - **...
通过代理数据库操作,Seata确保了跨服务操作的一致性,从而实现了分布式环境下的原子性。通过上述配置和代码实现,我们可以构建一个完整的微服务示例,展示Seata如何在实际场景中解决分布式事务问题。
《15、喂——出来》这篇微型科幻小说是由日本现代科幻小说家星新一创作的,以其独特的构思和丰富的想象力闻名。文体上,微型科幻小说的特点在于它篇幅短小,融合了科学事实、预见和想象,描绘了未来世界的生活和技术...
理解JMM有助于解决并发编程中的可见性、有序性和原子性问题。重点掌握volatile、final关键字的作用,了解happens-before原则,以及线程间的内存屏障。此外,还需理解内存泄漏和垃圾回收机制,确保程序的内存效率。 ...
- AOF(Append Only File):记录每次写操作的日志,确保数据安全性,但恢复速度较慢。 - 优缺点:RDB适合大数据量、对恢复时间要求不高的场景;AOF适合数据安全性要求高,允许少量数据丢失的场景。 3. **Redis ...
【描述】: 这份文档详细介绍了高中生物课程中的重点和难点——蛋白质,包括氨基酸的结构、蛋白质的合成与结构多样性,以及其功能。 【标签】: 精品文档 **详细知识点:** 1. **氨基酸的结构**: 氨基酸是蛋白质的...
【生命活动的主要承担者——蛋白质】是生物学中的重要概念,主要涵盖了两个主要的考点:蛋白质的结构和功能。 **考点一:组成蛋白质的氨基酸及其种类** 蛋白质的基本组成单位是氨基酸。氨基酸具有共同的核心结构,...
MySQL作为关系型数据库,遵循ACID(原子性、一致性、隔离性和持久性)原则,确保数据处理的准确性和可靠性。它支持SQL(Structured Query Language),这是一种统一、简洁且功能强大的语言,用于执行数据定义、查询...
3. Primordia 复数涓试:该测试项主要测试处理器对元素原子周暖的电子运算轨迹,通过对元素原子的电子运算轨迹进行测试,可以了解处理器对元素原子的电子运算能力。 Sciencemark 软件的使用非常简单,只需将软件...