oceanbase数据库支持语句级的原子性。
BEGIN; //开启事务
UPDATE T1 SET C1=1 WHERE C2=100; //执行成功
INSERT INTO T1 SELECT * FROM T2; //执行失败,回滚
COMMIT; //提交事务
事务执行结果:
UPDATE 执行成功,其更新结果被提交。
INSERT 执行失败,其所有 INSERT 的记录都被回滚。
在上述的示例中的结果和事务的原子性:“事务中的所有操作要么全部成功,要么全部失败”不会存在矛盾吗?语句级别的原子性默认是开启的吗?数据库默认是按照哪种原子性来运行的呢?
1 个赞
论坛小助手
#4
在 OceanBase 数据库中,确实存在事务级别的原子性和语句级别的原子性。事务级别的原子性是指事务中所有的操作要么全部成功,要么全部失败。而语句级别的原子性则是指单条语句的所有操作要么全部成功,要么全部失败,但不影响事务中其他语句的操作。
在您的示例中,事务执行的结果并不与事务的原子性相矛盾。具体来说,当 INSERT INTO T1 SELECT * FROM T2
语句执行失败时,只有该语句的操作会被回滚,而事务中之前执行成功的 UPDATE
语句的结果仍然会被提交。这是因为语句级别的原子性确保了单条语句的完整性,而不是整个事务的完整性。
在 OceanBase 数据库中,默认情况下是支持语句级别的原子性的,也就是说,每条语句的操作要么全部成功,要么全部失败。但是,事务级别的原子性仍然有效,即事务中的所有操作在最终提交时要么全部成功,要么全部失败。在这个例子中,事务最终提交时,只有 INSERT
语句的操作被回滚,而 UPDATE
语句的操作被提交,这符合语句级别的原子性和事务级别的原子性。
具体信息可参考以下文档:
- 语句级原子性
1 个赞
那在事务的原子性描述中,回滚也算是语句成功执行了吗?
在一个事务中,如:A用户转账100元给B用户
BEGIN; //开启事务
A用户-100元; //执行成功
B用户+100元; //执行失败,回滚
COMMIT; //提交事务
事务执行结果:
A用户-100元 执行成功,其更新结果被提交。
B用户+100元 执行失败,其被回滚。
那这样举例是否符合语句级别的原子性和事务级别的原子性呢? @论坛小助手
1 个赞
论坛小助手
#6
在您的例子中,A用户-100元和B用户+100元构成了一条事务。由于B用户+100元这条语句执行失败,根据OceanBase数据库的事务原子性原则,整个事务应被视为失败,所有对该事务所做的修改都应回滚,包括A用户-100元这一操作。这确保了语句级别的原子性,即单条SQL语句要么全部成功,要么全部失败。此外,也体现了事务级别的原子性,即一个事务内的所有操作要么全部成功,要么全部失败。在您给出的例子中,如果B用户的操作失败,整个事务应该被回滚,这意味着A用户账户减少的100元也应该恢复。因此,您提供的示例实际上不符合事务和语句级别的原子性,正确的结果应该是事务回滚,A用户和B用户的账户都不会发生改变。
更多信息请查看:
- 语句级原子性
- 使用 MySQL 租户做常见数据库开发
- MySQL 事务控制
示例1:
BEGIN; //开启事务
UPDATE T1 SET C1=1 WHERE C2=100; //执行成功
INSERT INTO T1 SELECT * FROM T2; //执行失败,回滚
COMMIT; //提交事务
事务执行结果:
UPDATE 执行成功,其更新结果被提交。
INSERT 执行失败,其所有 INSERT 的记录都被回滚。
示例2:
在一个事务中,如:A用户转账100元给B用户
BEGIN; //开启事务
A用户-100元; //执行成功
B用户+100元; //执行失败,回滚
COMMIT; //提交事务
事务执行结果:
A用户-100元 执行成功,其更新结果被提交。
B用户+100元 执行失败,其被回滚。
示例1和示例2中,为什么示例1符合语句级别的原子性和事务级别的原子性,而示例2不符合语句级别的原子性和事务级别的原子性呢? @论坛小助手
1 个赞
论坛小助手
#8
在OceanBase数据库中,事务和语句的执行遵循一定的规则,以确保数据的一致性和完整性。针对提供的示例,分析如下:
-
示例1:
BEGIN; // 开启事务
UPDATE T1 SET C1=1 WHERE C2=100; // 执行成功
INSERT INTO T1 SELECT * FROM T2; // 执行失败,回滚
COMMIT; // 提交事务
-
语句级别的原子性:在OceanBase数据库中,每条语句的执行要么全部成功,要么全部失败。在示例1中,
UPDATE
语句成功执行并提交,INSERT
语句失败并回滚。这符合语句级别的原子性。
-
事务级别的原子性:事务中的所有操作要么全部成功,要么全部失败。在这个例子中,虽然
INSERT
语句失败了,但是UPDATE
语句已经成功提交,不会因为INSERT
的失败而被回滚。因此,整个事务的结果是部分成功的,但仍然符合事务级别的原子性,因为每个语句都遵循了自身的原子性原则。
-
示例2:
BEGIN; // 开启事务
A用户-100元; // 执行成功
B用户+100元; // 执行失败,回滚
COMMIT; // 提交事务
-
语句级别的原子性:在OceanBase数据库中,每条语句的执行要么全部成功,要么全部失败。在示例2中,
A用户-100元
语句成功执行,B用户+100元
语句失败并回滚。这符合语句级别的原子性。
-
事务级别的原子性:事务中的所有操作要么全部成功,要么全部失败。在这个例子中,
B用户+100元
语句失败并回滚,导致整个事务被回滚。因此,A用户-100元
的更新也被回滚,整个事务没有留下任何副作用。这符合事务级别的原子性。
总结:
-
示例1符合语句级别的原子性和事务级别的原子性,因为每条语句都遵循了自己的原子性原则,即使
INSERT
语句失败,也不会影响已经成功提交的UPDATE
语句。
-
示例2符合语句级别的原子性,但不符合事务级别的原子性,因为在事务中,
B用户+100元
的失败导致整个事务回滚,包括已经成功执行的A用户-100元
。这确保了事务的整体一致性。
具体信息可参考以下文档:
- 语句级原子性
- MySQL 事务控制
- 使用 MySQL 租户做常见数据库开发
示例1:
BEGIN; //开启事务
UPDATE T1 SET C1=1 WHERE C2=100; //执行成功
INSERT INTO T1 SELECT * FROM T2; //执行失败,回滚
COMMIT; //提交事务
事务执行结果:
UPDATE 执行成功,其更新结果被提交。
INSERT 执行失败,其所有 INSERT 的记录都被回滚。
在这个示例中,insert执行失败,update不应该也回滚吗?事务的原子性update为什么会提交呢? @论坛小助手
1 个赞
论坛小助手
#10
在示例中,UPDATE 语句执行成功,而 INSERT 语句执行失败,这符合 OceanBase 数据库支持的语句级原子性。语句级的原子性意味着每条 SQL 语句要么全部成功,要么全部失败。在这个例子中,UPDATE 语句没有报错,因此它的更改被成功提交。而 INSERT 语句在执行过程中遇到错误,它自身所做的任何更改都会被回滚,但这不影响之前已经成功提交的 UPDATE 语句。这是因为语句级回滚只会回滚当前失败的那条语句所做的更改,而不会影响事务中其他已经成功提交的语句。因此,UPDATE 语句的更改仍然有效。
检索到的文档如下:
- 语句级原子性
- 回滚事务
- 使用 MySQL 租户做常见数据库开发
1 个赞
事务执行过程:
BEGIN;
UPDATE T1 SET C1=1 WHERE C2=100; // 成功
INSERT INTO T1 SELECT * FROM T2; // 失败 → 触发回滚
COMMIT; // 未实际执行(因INSERT失败导致事务回滚)
执行结果:
UPDATE 成功:该语句内部的修改是原子的,要么全部执行成功(更新所有符合条件的行),要么全部失败。此处成功执行。
INSERT 失败:该语句内部的修改是原子的,要么全部插入成功,要么全部不插入。
事务整体回滚:由于INSERT失败,整个事务被回滚,因此所有操作(包括UPDATE的修改)都被撤销,数据库状态恢复到事务开始前的状态。
符合原子性:
语句级原子性:每个语句的修改是独立原子的(UPDATE成功或失败,INSERT成功或失败)。
事务级原子性:整个事务要么全部提交(所有操作生效),要么全部回滚(所有操作撤销)。此处因INSERT失败,事务回滚,符合事务级原子性。
1 个赞