DOC菜单

交易

TIDB支持使用的分布式事务悲观乐观的交易模型。从TIDB 3.0.8开始,TIDB默认使用悲观事务模型。

本文档介绍了常用的交易相关的语句,显式和隐式事务,隔离级别,延迟检查约束和事务大小。

常见变量包括autocommittidb_disable_txn_auto_retry.tidb_retry_limit.,tidb_txn_mode

笔记:

tidb_disable_txn_auto_retry.tidb_retry_limit.变量只适用于乐观事务,不适用于悲观事务。

共同陈述

开始交易

陈述开始开始事务可以互换使用以明确启动新事务。

句法:

开始;
开始交易;
开始交易持续的快照;
开始交易因果关系仅限;

如果当前会话在执行这些语句之一时在事务的过程中,TIDB在开始新事务之前会自动提交当前事务。

笔记:

与MySQL不同,TIDB在执行上面的语句后拍摄当前数据库的快照。mysql开始开始事务执行第一个后拍摄快照选择声明(不是选择更新)从事务启动后从InnoDB读取数据。使用一致快照启动事务在执行语句期间拍摄快照。其结果,开始开始事务,使用一致快照启动事务相当于使用一致快照启动事务在MySQL。

提交交易

该声明犯罪指示TIDB应用当前事务中所做的所有更改。

句法:

犯罪;

提示:

确保您的应用程序正确处理了一个犯罪语句可以在启用之前返回错误乐观交易.如果您不确定您的应用程序如何处理此操作,则建议使用默认值悲观交易

回滚事务

该声明回滚回滚并取消当前事务中的所有更改。

句法:

回滚;

如果客户端连接被中止或关闭,事务也会自动回滚。

autocommit

根据MySQL兼容性所需,TIDB将默认情况下autocommit执行后立即进行陈述。

例如:

mysql>创建表格t1->ID基本的钥匙自动递增->PAD1.varchar.One hundred.->;查询好了0.做作的0.09mysql>选择@@autocommit.;+--------------+|@@autocommit.|+--------------+|1|+--------------+10.00mysql>插入t11“测试”;查询好了1做作的0.02mysql>回滚;查询好了0.做作的0.01mysql>选择*t1;+----+------+|ID|PAD1.|+----+------+|1|测试|+----+------+10.00

在上面的例子中,回滚声明没有效果。这是因为插入语句是在autocommit中执行的。也就是说,它相当于以下单一语句事务:

开始交易;插入t11“测试”;犯罪;

如果已明确启动事务,则无法应用AutoCommit。在以下示例中,回滚声明成功恢复了插入声明:

mysql>创建表格t2->ID基本的钥匙自动递增->PAD1.varchar.One hundred.->;查询好了0.做作的0.10mysql>选择@@autocommit.;+--------------+|@@autocommit.|+--------------+|1|+--------------+10.00mysql>开始交易;查询好了0.做作的0.00mysql>插入t21“测试”;查询好了1做作的0.02mysql>回滚;查询好了0.做作的0.00mysql>选择*t2;0.00

autocommit系统变量可以改变在全球或会议的基础上。

例如:

autocommit=0.;
全球的autocommit=0.;

显式和隐式事务

笔记:

有些陈述是隐式犯下的。例如,执行[开始|开始交易]隐式提交最后一个事务并启动一个新事务。这种行为是MySQL兼容性所必需的。指隐含的承诺更多细节。

TIDB支持显式交易(使用[开始|开始交易]犯罪定义事务的开始和结束)和隐式事务(设置autocommit = 1)。

如果设置值autocommit1并通过它开始新的交易[开始|开始交易]语句,自动车在之前禁用犯罪回滚这使得事务变得显式。

对于DDL语句,事务自动提交,不支持回滚。如果在当前会话处于事务的过程时运行DDL语句,则在提交当前事务后执行DDL语句。

懒惰检查约束

默认情况下,乐观事务不会检查首要的关键独特的约束执行DML语句时。改用这些检查在交易上执行犯罪

例如:

创建表格t1ID基本的钥匙;插入t11;开始乐观的;插入t11;MySQL返回错误;TiDB返回成功。插入t12;犯罪;- 它在mysql中成功致力于;TIDB返回错误,事务回滚。选择*t1;-  MySQL返回1 2;TIDB返回1。
mysql>创建表格t1ID基本的钥匙;查询好了0.做作的0.10mysql>插入t11;查询好了1做作的0.02mysql>开始乐观的;查询好了0.做作的0.00mysql>插入t11;MySQL返回错误;TiDB返回成功。查询好了1做作的0.00mysql>插入t12;查询好了1做作的0.00mysql>犯罪;- 它在mysql中成功致力于;TIDB返回错误,事务回滚。错误1062.23000.复制条目'1'为了关键'基本的'mysql>选择*t1;-  MySQL返回1 2;TIDB返回1。+----+|ID|+----+|1|+----+10.01

延迟检查优化通过批量约束检查和降低网络通信来提高性能。可以通过设置禁用行为tidb_constraint_check_in_place = true

笔记:

  • 这种优化仅适用于乐观事务。
  • 这种优化不会生效插入忽略插入重复密钥更新,但仅限于正常使用插入语句。

声明回滚

TiDB支持语句执行失败后的原子回滚。如果语句导致错误,则它所做的更改将不会生效。该交易将保持开放,并且可以在发布一个犯罪回滚声明。

创建表格测试ID基本的钥匙;开始;插入测试1;插入tset2;- 声明不会生效,因为“测试”被拼写为“tset”。插入测试12;- 整个语句不会生效,因为它违反了主键约束插入测试3.;犯罪;选择*测试;
mysql>创建表格测试ID基本的钥匙;查询好了0.做作的0.09mysql>开始;查询好了0.做作的0.00mysql>插入测试1;查询好了1做作的0.02mysql>插入tset2;- 声明不会生效,因为“测试”被拼写为“tset”。错误1146.42S02表格'test.tyet'没有mysql> INSERT INTO test VALUES (1),(2);ERROR 1062 (23000): Duplicate entry '(重复条目)1'关键'基本的'mysql.>插入测试3.;查询好了1做作的0.00mysql>犯罪;查询好了0.做作的0.01mysql>选择*测试;+----+|ID|+----+|1||3.|+----+20.00

在上面的例子中,事务在失败后仍然是打开的插入语句。最后一条插入语句成功,并提交更改。

交易规模限制

由于底层存储引擎的局限性,TIDB需要单行不超过6 MB。行的所有列根据其数据类型转换为字节,并总结为估计单行的大小。

TiDB支持乐观事务和悲观事务,乐观事务是悲观事务的基础。由于乐观事务首先将更改缓存到私有内存中,TiDB限制了单个事务的大小。

默认情况下,TiDB将单个事务的总大小设置为不超过100 MBtxn-total-size-limit在配置文件中。最大值txn-total-size-limit是10 GB。

实际的单个事务大小限制也取决于服务器可用的剩余内存量,因为执行事务时,TIDB进程的内存使用率大约是交易大小的六倍。

TIDB先前限制了单个交易的键值对的总数为300,000。在TIDB V4.0中删除了该限制。

笔记:

通常,TIDB Binlog已启用以将数据复制到下游。在某些情况下,诸如Kafka等消息中间件用于消耗复制到下游的Binlogs。

以kafka为例,Kafka的单个消息处理能力的上限为1 GB。因此,什么时候txn-total-size-limit设置为1 GB以上,可能发生在TIDB中成功执行事务,但下游Kafka报告错误。要避免这种情况,您需要决定实际的价值txn-total-size-limit根据最终消费者的限制。例如,如果kafka在下游使用,txn-total-size-limit不能超过1gb。

因果关系

笔记:

具有因果关系的事务仅在启用异步提交和单相提交功能时生效。有关两个功能的详细信息,请参阅tidb_enable_async_commit.tidb_enable_1pc

TIDB支持实现交易的因果关系。具有因果一致性的事务,在提交时,不需要从PD获取时间戳并具有较低的提交延迟。启用因果关系的语法如下:

开始交易因果关系仅限;

默认情况下,TIDB保证线性一致性。在线性一致性的情况下,如果在事务1之后提交事务2,则逻辑上,事务2应在事务1之后发生事务2。因果关系比线性一致性较弱。在因果一致性的情况下,只有当交易1和事务2所锁定或写入的数据具有交叉点时,才能保证两次交易的提交订单和发生阶数,这意味着这两个交易具有已知的因果关系数据库。目前,TIDB不支持通过外部因果关系。

启用了两个因果一致性的两次交易具有以下特征:

具有潜在因果关系的交易具有一致的逻辑秩序和物理提交订单

假设事务1和事务2都采用了因果关系,并执行以下陈述:

交易1 交易2
仅以因果一致性启动事务 仅以因果一致性启动事务
x =从t中选择v,其中id = 1进行更新
更新t set v = $(x + 1),其中id = 2
犯罪
UPDATE t SET v = 2 WHERE id = 1
犯罪

在上面的示例中,事务1锁定ID = 1记录和交易2修改了ID = 1记录。因此,交易1和交易2具有潜在的因果关系。即使通过启用的因果关系,只要在交易1成功提交交易2之后,逻辑上,事务2必须在交易1之后发生。因此,事务读取交易2的修改是不可能的ID = 1对象上不读取事务1的修改的记录ID = 2记录。

没有因果关系的事务不能保证一致的逻辑顺序和物理提交顺序

假设的初值ID = 1ID = 2都是0..假设事务1和事务2都采用了因果关系,并执行以下陈述:

交易1 交易2 交易3.
仅以因果一致性启动事务 仅以因果一致性启动事务
更新T SET V = 3其中ID = 2
UPDATE t SET v = 2 WHERE id = 1
开始
犯罪
犯罪
从T中选择v(1,2)

在上面的例子中,事务1不读取ID = 1记录,因此交易1和事务2没有数据库已知的因果关系。对于交易启用的因果关系,即使事务2在事务1以物理时间顺序提交之后,也不保证交易2在交易1之后逻辑地发生事务2。

如果事务3在事务1提交之前开始,并且事务3读取ID = 1ID = 2事务2后记录已提交,事务3可能会读取值ID = 12但是ID = 20.

没有锁的读取不创造因果关系

假设事务1和事务2都采用了因果关系,并执行以下陈述:

交易1 交易2
仅以因果一致性启动事务 仅以因果一致性启动事务
UPDATE t SET v = 2 WHERE id = 1
从t中选择v其中id = 1
更新T SET V = 3其中ID = 2
犯罪
犯罪

在上面的例子中,没有锁的读取不会创建因果关系。事务1和事务2已经创建了写倾斜。在这种情况下,如果两笔交易仍然存在因果关系,那就不合理了。因此,启用因果一致性的两个事务没有确定的逻辑顺序。