首页 > 问答 > 关键词  > MySQL最新资讯  > 正文

为什么MySQL默认隔离级别是RR

2020-07-02 11:35 · 稿源:数据库干货铺

曾多次听到“MySQL为什么选择RR为默认隔离级别”的问题,其实这是个历史遗留问题,当前以及解决,但是MySQL的各个版本沿用了原有习惯。历史版本中的问题是什么,本次就通过简单的测试来说明一下。

1、 准备工作

1.1 部署主从

部署一套主从架构的集群,创建过程较简单,可以参考历史文章部署MySQL主从复制搭建部署一主一从即可。

1.2 创建测试表及数据

在主库中创建表及测试数据

mysql>createtableusers(idintprimarykeyauto_increment,user_namevarchar(20),c_idtinyint(4),c_notevarchar(50),keyc_id(c_id))engine=innodb;
QueryOK,0rowsaffected(0.01sec)
mysql>insertintousersvalues(1,'刘备',2,null),(2,'曹操',1,null),(3,'孙权',3,null),(4,'关羽',2,null),(5,'司马懿',1,null);
QueryOK,5rowsaffected(0.00sec)
Records:5Duplicates:0Warnings:0mysql>createtableclass(c_idintprimarykey,c_namevarchar(1),c_notevarchar(50))engine=innodb;
QueryOK,0rowsaffected(0.00sec)
mysql>insertintoclassvalues(1,'魏',null),(2,'蜀',null),(3,'吴',null),(4,'晋','');
QueryOK,4rowsaffected(0.00sec)
Records:4Duplicates:0Warnings:0

2、 RR隔离级别

MySQL默认的隔离级别为 RR(Repeatable Read),在此隔离级别下,对比binlog格式为ROW、STATEMENT是否会造成主从数据不一致

2.1 ROW格式

其实不用测试大家也应该对RR级别下ROW格式的binlog有信心,但是,万事皆需实践检验。

步骤说明如下:

  • 步骤1 - 分别查看两个会话中的事务隔离级别及binlog格式(隔离级别均为RR,binlog为ROW格式)
  • 步骤2 - SESSION A 开启事务,更新users 表中c_id字段存在于class表中的记录,结果为 5 条记录均更新,并将c_note内容更新为 t1
  • 步骤3- SESSION B 开启事务,准备删除class表中 c_id等于 2 的记录,此时无法更新,处于阻塞状态,因为在RR级别下需要保证重复读。达到所等待超时时间后将会报错。
  • 步骤4- SESSION A 提交事务(此步骤也可以在步骤 3 时操作,结果不一样,后续步骤中将采用此方式)
  • 步骤5- SESSION B 重启事务,再次删除class表中 c_id等于 2 的记录,此时提交可以成功了,成功删除了一条记录
  • 步骤6- SESSION A 开启事务,更新users 表中c_id字段存在于class表中的记录,结果为 3 条记录更新成功,并将c_note内容更新为 t2,有 2 条记录因为c_id不存在与class表中,因此不会更新
  • 步骤7- 分别在SESSON A和SESSION B查看users表中的内容,结果一致
  • 步骤8- 在从库查看users表中的内容,数据与主库一致

具体步骤如下:

步骤SESSION A

SESSION B

1

mysql>show variables like '%iso%';

+-----------------------+-----------------+

| Variable_name | Value |

+-----------------------+-----------------+

| transaction_isolation | REPEATABLE-READ |

| tx_isolation | REPEATABLE-READ |

+-----------------------+-----------------+

2 rows in set (0.00 sec)

mysql>show variables like '%binlog_format%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| binlog_format | ROW |

+---------------+-------+

1 row in set (0.00 sec)

mysql>show variables like '%iso%';

+-----------------------+-----------------+

| Variable_name | Value |

+-----------------------+-----------------+

| transaction_isolation | REPEATABLE-READ |

| tx_isolation | REPEATABLE-READ |

+-----------------------+-----------------+

2 rows in set (0.00 sec)

mysql>show variables like '%binlog_format%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| binlog_format | ROW |

+---------------+-------+

1 row in set (0.01 sec)

2

mysql>set autocommit=0;

mysql>update users set c_note='t1' where c_id in (select c_id from class);

Query OK, 5 rows affected (0.00 sec)

Rows matched: 5 Changed: 5 Warnings: 0

3

mysql>set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

mysql>delete from class where c_id=2;

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

4

mysql>commit;

Query OK, 0 rows affected (0.00 sec)

5

mysql>set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

mysql>delete from class where c_id=2;

Query OK, 1 row affected (0.00 sec)

mysql>commit;

Query OK, 0 rows affected (0.00 sec)

6

mysql>update users set c_note='t2' where c_id in (select c_id from class);

Query OK, 3 rows affected (0.00 sec)

Rows matched: 3 Changed: 3 Warnings: 0

mysql>commit;

Query OK, 0 rows affected (0.00 sec)

7

mysql>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

mysql>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

8

在从库查看数据

root@testdb:3307 12:02:20>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

2.2 STATEMENT格式

为了和之前的步骤一致,先初始化数据

root@testdb:330612:14:27>truncatetableusers;
QueryOK,0rowsaffected(0.08sec)
root@testdb:330612:14:29>truncatetableclass;
QueryOK,0rowsaffected(0.04sec)
root@testdb:330612:14:50>insertintousersvalues(1,'刘备',2,null),(2,'曹操',1,null),(3,'孙权',3,null),(4,'关羽',2,null),(5,'司马懿',1,null);
QueryOK,5rowsaffected(0.00sec)
Records:5Duplicates:0Warnings:0root@testdb:330612:15:10>insertintoclassvalues(1,'魏',null),(2,'蜀',null),(3,'吴',null),(4,'晋','');
QueryOK,4rowsaffected(0.00sec)
Records:4Duplicates:0Warnings:0

再将binlog日志格式改为STATAMENT格式(全局及会话级都改一下,或者修改全局变量后重新登录也行,当然 只改会话级别的也可以测试),然后 再次进行测试。

步骤说明如下:

  • 步骤1 - 分别查看两个会话中的事务隔离级别及binlog格式(隔离级别均为RR,binlog为STATENENT格式)
  • 步骤2 - SESSION A 开启事务,更新users 表中c_id字段存在于class表中的记录,结果为 5 条记录均更新,并将c_note内容更新为 t1
  • 步骤3- SESSION B 开启事务,准备删除class表中 c_id等于 2 的记录,此时无法更新,处于阻塞状态,立即进行步骤4
  • 步骤4- SESSION A 在SESSION B执行commit的动作,则SESSION B的删除操作可以执行通过,但注意class表的数据两个SESSION中查看到的是不一样的
  • 步骤5- 此时SESSION B执行commit,否则后面session A 更新数据时也会阻塞。此时如果SESSION A不执行commit,查看class表的结果也是不一样的,如步骤中的情况
  • 步骤6- SESSION A 开启事务,更新users 表中c_id字段存在于class表中的记录,结果为 3 条记录更新成功,并将c_note内容更新为 t2,另外 2 条记录虽然本此时查看class表中存在对应的c_id,但是不会更新,此时提交事务,然后再次查看class的内容,结果和SESSION B 查看的结果一致了(幻读)
  • 步骤7- 在从库查看users、class表中的内容,数据与主库一致
步 骤SESSION ASESSION B
1

mysql>show variables like '%iso%';

+-----------------------+-----------------+

| Variable_name | Value |

+-----------------------+-----------------+

| transaction_isolation | REPEATABLE-READ |

| tx_isolation | REPEATABLE-READ |

+-----------------------+-----------------+

2 rows in set (0.01 sec)

mysql>show variables like '%binlog_format%';

+---------------+-----------+

| Variable_name | Value |

+---------------+-----------+

| binlog_format | STATEMENT |

+---------------+-----------+

1 row in set (0.01 sec)

mysql>show variables like '%iso%';

+-----------------------+-----------------+

| Variable_name | Value |

+-----------------------+-----------------+

| transaction_isolation | REPEATABLE-READ |

| tx_isolation | REPEATABLE-READ |

+-----------------------+-----------------+

2 rows in set (0.01 sec)

mysql>show variables like '%binlog_format%';

+---------------+-----------+

| Variable_name | Value |

+---------------+-----------+

| binlog_format | STATEMENT |

+---------------+-----------+

1 row in set (0.01 sec)

2

root@testdb:3306 12:37:04>set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 12:37:17>update users set c_note='t1' where c_id in (select c_id from class);

Query OK, 5 rows affected, 1 warning (0.00 sec)

Rows matched: 5 Changed: 5 Warnings: 1

3

root@testdb:3306 12:28:25>set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 12:38:06>delete from class where c_id=2;

Query OK, 1 row affected (4.74 sec)

4

root@testdb:3306 12:38:09>commit;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 12:38:13>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t1 |

| 3 | 孙 权 | 3 | t1 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t1 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

root@testdb:3306 12:39:07>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 2 | 蜀 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

4 rows in set (0.00 sec)

5

root@testdb:3306 12:38:13>commit;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 12:39:56>select * from class ;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

3 rows in set (0.00 sec)

6

root@testdb:3306 12:52:23>update users set c_note='t2' where c_id in (select c_id from class);

Query OK, 3 rows affected, 1 warning (0.00 sec)

Rows matched: 3 Changed: 3 Warnings: 1

root@testdb:3306 12:52:45>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 2 | 蜀 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

4 rows in set (0.00 sec)

root@testdb:3306 12:52:49>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙 权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.01 sec)

root@testdb:3306 12:53:03>commit;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 12:53:06>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙 权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

root@testdb:3306 12:53:11>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

3 rows in set (0.00 sec)

7

查看从库数据

root@testdb:3307 12:44:22>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

3 rows in set (0.01 sec)

root@testdb:3307 12:57:07>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙 权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

也就是此时主从结果也是一致的,原因在于,binlog里存储的语句顺序如下:

binlog里的顺序语句内容
1

update users set c_note='t1' where c_id in (select c_id from class);

2delete from class where c_id=2;
3update users set c_note='t2' where c_id in (select c_id from class);

与主库执行的顺序是一致的,因此,主从的结果是一致的。

3、 RC隔离级别

3.1 ROW格式

为了和之前的步骤一致,先初始化数据

root@testdb:330612:14:27>truncatetableusers;
QueryOK,0rowsaffected(0.08sec)
root@testdb:330612:14:29>truncatetableclass;
QueryOK,0rowsaffected(0.04sec)
root@testdb:330612:14:50>insertintousersvalues(1,'刘备',2,null),(2,'曹操',1,null),(3,'孙权',3,null),(4,'关羽',2,null),(5,'司马懿',1,null);
QueryOK,5rowsaffected(0.00sec)
Records:5Duplicates:0Warnings:0root@testdb:330612:15:10>insertintoclassvalues(1,'魏',null),(2,'蜀',null),(3,'吴',null),(4,'晋','');
QueryOK,4rowsaffected(0.00sec)
Records:4Duplicates:0Warnings:0

再将binlog日志格式改为STATAMENT格式(全局及会话级都改一下,或者修改全局变量后重新登录也行,当然 只改会话级别的也可以测试),然后 再次进行测试。

步骤说明如下:

  • 步骤1 - 分别查看两个会话中的事务隔离级别及binlog格式(隔离级别均为RC,binlog为ROW格式)
  • 步骤2 - SESSION A 开启事务,更新users 表中c_id字段存在于class表中的记录,结果为 5 条记录均更新,并将c_note内容更新为 t1
  • 步骤3- SESSION B 开启事务,准备删除class表中 c_id等于 2 的记录,此时不会像RR事务隔离级别那样处于阻塞状态,而是可以直接执行通过
  • 步骤4- 此时SESSION A查看class数据还是删除前的,因为session B 暂未提交
  • 步骤5- SESSION B 提交事务,
  • 步骤6- 更新users 表中c_id字段存在于class表中的记录,结果为 3 条记录更新成功,并将c_note内容更新为 t2
  • 步骤7- 在从库查看users、class表中的内容,数据与主库一致
步 骤SESSION ASESSION B
1

root@testdb:3306 01:25:24>show variables like '%iso%';

+-----------------------+----------------+

| Variable_name | Value |

+-----------------------+----------------+

| transaction_isolation | READ-COMMITTED |

| tx_isolation | READ-COMMITTED |

+-----------------------+----------------+

2 rows in set (0.01 sec)

root@testdb:3306 01:25:36>show variables like '%binlog_format%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| binlog_format | ROW |

+---------------+-------+

1 row in set (0.01 sec)

root@testdb:3306 01:24:57>show variables like '%iso%';

+-----------------------+----------------+

| Variable_name | Value |

+-----------------------+----------------+

| transaction_isolation | READ-COMMITTED |

| tx_isolation | READ-COMMITTED |

+-----------------------+----------------+

2 rows in set (0.01 sec)

root@testdb:3306 01:25:39>show variables like '%binlog_format%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| binlog_format | ROW |

+---------------+-------+

1 row in set (0.00 sec)

2

root@testdb:3306 01:27:55>set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 01:28:27>update users set c_note='t1' where c_id in (select c_id from class);

Query OK, 5 rows affected (0.00 sec)

Rows matched: 5 Changed: 5 Warnings: 0

3

root@testdb:3306 01:26:07>set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 01:28:37>delete from class where c_id=2;

Query OK, 1 row affected (0.00 sec)

4

root@testdb:3306 01:28:27>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 2 | 蜀 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

4 rows in set (0.00 sec)

5

root@testdb:3306 01:28:41>commit;

Query OK, 0 rows affected (0.00 sec)

6

root@testdb:3306 01:28:59>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

3 rows in set (0.01 sec)

root@testdb:3306 01:29:13>update users set c_note='t2' where c_id in (select c_id from class);

Query OK, 3 rows affected (0.00 sec)

Rows matched: 3 Changed: 3 Warnings: 0

root@testdb:3306 01:29:26>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

3 rows in set (0.00 sec)

root@testdb:3306 01:29:31>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙 权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

root@testdb:3306 01:29:38>commit;

7

查看从库数据

root@testdb:3307 01:40:32>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙 权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

root@testdb:3307 01:40:35>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

3 rows in set (0.00 sec)

也就是此时主从结果也是一致的。

3.2 STATEMENT格式

因为当前版本已经不支持RC+STATEMENT组合下数据的操作,否则将报如下错误:

Cannotexecutestatement:impossibletowritetobinarylogsinceBINLOG_FORMAT=STATEMENTandatleastonetableusesastorageenginelimitedtorow-basedlogging.InnoDBislimitedtorow-loggingwhentransactionisolationlevelisREADCOMMITTEDorREADUNCOMMITTED.

因此单纯根据步骤讲解

步骤SESSION ASESSION B
1

mysql>set autocommit=0;

mysql>update users set c_note='t1' where c_id in (select c_id from class);

2

mysql>set autocommit=0;

mysql>delete from class where c_id=2;

mysql>commit;

3mysql>update users set c_note='t2' where c_id in (select c_id from class);
4commit;

因为binlog是按照commit时间的顺序保存,因此上述步骤在binlog里会以如下顺序存储:

binlog里的顺序语句内容
1

delete from class where c_id=2;

2update users set c_note='t1' where c_id in (select c_id from class);
3update users set c_note='t2' where c_id in (select c_id from class);

从库通过binlog应用后,最终的结果将导致主库的数据不一样(具体案例后续安装低版本后演示)。

因而,此种场景下很容易导致数据不一样。

4、总结

通过上述的实践,可以发现在RR级别下,binlog为任何格式均不会造成主从数据不一致的情况出现,但是当低版本MySQL使用RC+STATEMENT组合时(MySQL5.1. 5 前只有statement格式)将会导致主从数据不一致。当前这个历史遗漏问题以及解决,大家可以将其设置为RC+ROW组合的方式(例如ORACLE等数据库隔离级别就是RC),而不是必须使用RR(会带来更多的锁等待),具体可以视情况选择。

本文转载自微信公众号【数据库干货铺】。

举报

  • 相关推荐
  • 大家在看
  • Video2Game:从单一视频创建实时互动游戏环境

    Video2Game是一项技术,可以将单一视频转换成具有实时、互动、真实感和浏览器兼容性的高质量虚拟环境。它通过构建大规模的NeRF模型来实现高质量的表面几何形状,然后将该模型转换为带有对应刚体动力学的网格表示,以支持交互。使用UV映射的神经纹理,既能表达丰富,又与游戏引擎兼容。最终得到的是一个虚拟环境,虚拟角色可以与之互动,响应用户控制,并能从新的相机视角实时提供高分辨率渲染。

  • Cohere Compass:多方面数据索引与搜索模型

    Cohere Compass是一款新型的多方面嵌入模型,专为解决企业数据中的多重概念和关系检索挑战而设计。它能够将数据以JSON格式传递至嵌入模型,转换后存储在向量数据库中,保持元数据和文本的同时,捕捉多方面数据中概念间的关系。与传统的RAG流程相比,Compass通过其SDK将电子邮件及其附件解析为单一JSON,生成包含多方面表示的嵌入输出,从而在搜索时能够准确理解和匹配查询中的不同方面。

  • Ctrl-Adapter:视频生成的精细控制工具

    Ctrl-Adapter是一个专门为视频生成设计的Controlnet,提供图像和视频的精细控制功能,优化视频时间对齐,适配多种基础模型,具备视频编辑能力,显著提升视频生成效率和质量。

  • Reka Core:强大的多模态LLM,商业解决方案

    Reka Core是一个GPT-4级别的多模态大型语言模型(LLM),具备图像、视频和音频的强大上下文理解能力。它是目前市场上仅有的两个商用综合多模态解决方案之一。Core在多模态理解、推理能力、编码和Agent工作流程、多语言支持以及部署灵活性方面表现出色。

  • 2txt:快速将图片中的文字转换为可编辑文本

    2txt是一个在线OCR工具,能够将图片中的文字内容快速识别并转换成可编辑的文本格式。它支持多种语言的识别,并且操作简单,用户只需上传图片即可获得结果。该工具不存储用户上传的图片,保证了用户数据的隐私安全。

  • 法行宝:AI智能法律分析工具

    法行宝是一款集成了人工智能技术的法律服务平台,旨在为用户提供专业的法律意见和文书参考。通过预设问题引导用户提供必要信息,结合《中华人民共和国民法典》等相关法律法规,生成详细的法律意见书。法行宝不仅提供离婚流程指导、文书模板下载,还包含人性化的行动建议和扩展资料,帮助用户全面理解并应对法律问题。

  • Adobe Acrobat AI Assistant:AI智能助手,文档快速理解与生成

    Adobe Acrobat的AI助手是一个集成在Acrobat中的创新功能,它可以帮助用户通过提问来理解文档内容,快速获取信息并生成内容。这项功能特别适合需要从文档中提取关键信息并快速创建电子邮件、演示文稿、会议记录等的用户。AI助手可以生成文档摘要,提供基于文档内容的建议问题,帮助用户更有效地探索和理解内容。此外,Adobe Acrobat的AI助手遵循Adobe的AI伦理原则,确保用户数据的安全和透明。

  • AI Voice Generator Bot:使用人工智能将文本转换为音频

    AI语音生成器是一个简单易用的产品,它使用人工智能技术将文本转换为音频。它提供了多达25种不同的声音,完美演绎英语。您只需在Telegram上输入文本,我们即可回复相应的音频,无需等待。立即试用,快速将文本转换为语音。

  • Glaze:保护艺术家风格的AI工具

    Glaze是一个旨在保护人类艺术家免受AI风格模仿的系统。通过机器学习算法对艺术作品进行微小改动,使其对人类眼睛看起来不变,但对AI模型则呈现出完全不同的艺术风格。这样,当有人试图模仿特定艺术家的风格时,AI生成的结果将与预期大相径庭。Glaze不是永久解决方案,但是一个必要的第一步,为艺术家提供抵抗AI模仿的工具。

  • FastBots:无需编码,快速创建AI聊天机器人

    FastBots.ai是一个强大的AI聊天机器人平台,允许用户通过上传自己的数据,如网站内容、文档、PDF文件等,来训练并创建定制化的聊天机器人。这些机器人可以无缝集成到网站中,提供24/7的客户支持、销售辅助、个人助理等多种功能。FastBots.ai支持95种语言,提供军事级别的数据加密,无需编程即可通过简单的复制粘贴代码嵌入聊天机器人,还支持与超过5000个应用程序通过Zapier集成。

  • Limitless:超越思维限制的个性化AI助手

    Limitless是一款由人工智能驱动的生产力工具,旨在帮助用户突破思维限制,通过保存对话和提供个性化AI问答来增强记忆力和专注力。产品形态包括可穿戴设备和应用程序,支持会议准备、实时转录、自动笔记和会议总结等功能,无需额外的机器人加入会议,且提供无限存储空间。

  • Adobe Premiere Pro:AI驱动的视频编辑软件

    Adobe Premiere Pro是一款功能强大的视频编辑软件,集成了AI技术,旨在简化复杂的编辑任务并加速编辑流程。软件提供了文本基础编辑、音频分类标签、语音转文字、增强语音、场景检测、自动色彩调整、形态变换、颜色匹配、音频自动调节、自动重构等功能,大大提高了编辑效率和创作可能性。Premiere Pro适用于社交媒体短视频制作到长片电影的编辑,帮助用户节省时间,专注于创意和故事讲述。今年晚些时候,Adobe Premiere Pro计划推出第三方AI模型功能,使编辑人员能够选择最适合其素材的模型,从而提升编辑体验。这些AI模型包括OpenAI的Sora模型、Runway AI和Pika的视频模型。此外,Premiere Pro还将提供内容验证功能,帮助用户了解他们是否使用了AI以及使用了哪个模型来进行媒体创作。

  • SuperMemory:用打造你的第二大脑

    supermemory是一个帮助用户整理和回顾互联网上保存内容的工具,类似于为书签打造的ChatGPT。用户可以通过导入推文或使用Chrome扩展保存网站和内容。它包含三个主要模块:主Web UI、Chrome扩展和AI后端处理。旨在帮助用户更有效地管理和回顾信息,提高生产力。

  • Pile-T5:基于Pile数据集训练的T5模型

    Pile-T5是EleutherAI推出的一款自然语言处理模型,它在原有的T5模型基础上,采用了Pile数据集和LLAMA分词器进行训练,以改善对代码任务的理解能力。该模型经过了2万亿个token的训练,是原T5模型训练量的两倍。Pile-T5在多项下游任务中表现出色,尤其是在代码相关任务上。此外,EleutherAI还提供了中间检查点,以便研究人员研究模型随时间的演变。

  • SoraPix AI:创建您梦想中的动漫女孩

    SoraPix是一个AI驱动的图片生成工具,内置多种独特模型,通过简单的几步操作,您可以创建您梦想中的动漫女孩。SoraPix提供衣橱、动漫和图片生成等功能,具有4K高清图像质量和更快的服务速度。您可以通过购买宝石来解锁更多功能和选择。

  • PostHunt:写病毒式推特,AI辅助

    PostHunt是一款通过AI辅助撰写病毒式推特的工具。用户可以描述内容、选择模板,快速在Twitter上获得病毒式传播。PostHunt结合了GPT 4、Claude 3和Gemini 1.5 Pro的强大功能,使用者可以通过三个简单步骤,在15秒内撰写一条病毒式推特。100多位创作者选择了PostHunt,用于撰写病毒式推特,其强大的功能和简单易用的界面备受好评。

  • MejoraImagen:提升图片质量

    MejoraImagen是一个在线图片增强工具,使用智能算法提升像素化、低分辨率、光线不佳等问题的图片质量。只需上传图片到我们的表单,几秒钟内就能得到100%增强的结果。

  • Azyri:AI医疗助手,为您的医疗团队提供最佳支持

    Azyri是一款AI医疗助手,通过骨龄测量和分析,为医疗团队提供准确的诊断和治疗建议。优势包括减轻医疗团队工作负担,提高工作效率,定价根据服务套餐而定。主要功能包括骨龄测量、诊断X射线、医学影像和机器智能分析。

  • Rhea:生成高质量的短视频

    Rhea是一款由人工智能驱动的短视频生成平台。它可以通过文本输入生成高质量、快速、引人入胜的短视频。Rhea还可以为您的视频生成字幕,使其更具可访问性。您还可以自定义字幕的样式,以与您的品牌相匹配。您可以根据需要定制视频的风格,例如使用定制的配色方案和字体。Rhea适用于各种用途的视频生成,从教育内容到营销视频不一而足。

  • LIDO:一键生成独特的AI音乐,为您的歌曲、TikToks、Reels等创作无版权的音乐。

    LIDO是一款AI音乐生成器,可以快速生成带有自定义歌词和风格的独特歌曲。无论您是新手音乐人还是想要探索音乐无限可能性的人,LIDO都是您释放创造力的一站式解决方案。它生成的音乐具有无版权,可以用于您的歌曲、TikToks、Reels等。定价信息请访问官网了解。

今日大家都在搜的词: