当前位置: 首页 > news >正文

【MySQL精通之路】InnoDB(7)-锁和事务模型(2)-事务模型

主博客:

【MySQL精通之路】InnoDB(7)-锁和事务模型-CSDN博客

上一篇:

【MySQL精通之路】InnoDB(7)-锁和事务模型(1)-锁-CSDN博客

下一篇:

 

目录

1.事务隔离级别

2.1 可重复读

2.2 读已提交

2.3 读取未提交

2.4 序列化读

2.自动提交、提交和回滚

2.1 将DML操作以事务分组

2.2 客户端语言的事务

3.无锁快照读

4.锁读取

4.1 SELECT ... FOR SHARE

4.2 SELECT ... FOR UPDATE

4.3 加锁读示例

5 使用NOWAIT和SKIP LOCKED实现加锁读并发


 

InnoDB事务模型旨在将多版本数据库的最佳属性(MVCC)与传统的两阶段锁相结合。

InnoDB支持行锁,默认情况下以Oracle的风格尽量不使用锁,因此以快照读的方式来查询数据。

InnoDB中的锁的信息被高效存储着,因此不需要扩增锁的存储空间。

通常,允许几个用户锁定InnoDB表中的每一行,或行的任何随机子集,而不会导致InnoDB内存耗尽。

1.事务隔离级别

事务隔离是数据库处理的基础之一。隔离是缩写词ACID中的I(Isolation);隔离级别是在多个事务同时进行更改和查询时对性能与结果的可靠性一致性可再现性之间的平衡进行微调的设置。

InnoDB提供了SQL:1992标准所描述的所有四个事务隔离级别:

READ UNCOMITTED:读未提交

READ COMMITTED:读提交

REPEATABLE READ:可重复读

SERIALIZABLE:串行化

InnoDB的默认隔离级别是REPEATABLE READ

用户可以使用SET TRANSACTION语句更改单个会话所有后续连接隔离级别

要为所有连接设置服务器的默认隔离级别,请在命令行或选项文件中使用

--transaction-isolation

选项。有关隔离级别和级别设置语法的详细信息,请参阅“SET TRANSACTION语句”。

 

InnoDB使用不同的锁策略来支持这里描述的每个事务隔离级别

对于ACID严格要求的数据操作,您可以使用默认的REPEATABLE READ级别强制实现高度一致性

或者,您可以使用READ COMMITTED甚至READ UNCOMITTED放宽一致性规则,在产生日志记录等类型务场景下,精确的一致性和可重复的结果不如最小化锁的开销重性价比高。

SERIALIZABLE执行比REPEATABLE READ更严格的规则,主要用于特殊情况,如XA事务以及并发死锁问题故障排除

以下列表描述MySQL如何支持不同的事务级别。该列表描述了从最常用的隔离级别最不常用的级别

2.1 可重复读

这是InnoDB的默认隔离级别。

同一事务中的查询操作总是查询第一次查询时建立的快照数据

这意味着,如果在同一事务中发出多个纯(无锁查询)SELECT语句,这些SELECT语句彼此之间的数据结果也是一致的。

参见“一致无锁读取”。

对于有锁读取SELECT ... FOR UPDATE or FOR SHARE)、UPDATEDELETE语句,锁取决于该语句是使用具有唯一搜索条件的唯一索引,还是使用范围查询的查询条件。

2.1.1 唯一索引下的可重复读

对于具有唯一搜索条件的唯一索引,InnoDB只锁定找到的索引记录,而不锁定之前的间隙

博主ps:由于查询数据可以根据唯一索引查到数据,隐藏就算有其他数据插入进来,或有数据被删除,也不影响我的数据一致性。

2.1.2 其他索引下的可重复读

对于其他搜索条件,InnoDB会锁定扫描到的索引的范围,使用间隙锁临键锁阻止其他会话插入到范围覆盖的间隙中。有关间隙锁临键锁的信息,请参阅“InnoDB锁”。

【MySQL精通之路】Innodb-锁和事务-CSDN博客

2.2 读已提交

即使在同一事务中,每次一致读取都会设置读取自己的新快照

有关一致读取的信息,请参阅“一致无锁读取”。

对于有锁读取(SELECT with FOR UPDATE or FOR SHARE)、UPDATE语句和DELETE语句

InnoDB只锁定索引记录,而不锁定它们之前的间隙,因此允许在锁定行之后自由插入新记录。

间隙锁仅用于外键约束检查重复key检查

由于间隙锁被禁用,可能会出现幻行问题,因为其他会话可以将新行插入间隙中。

有关幻行的信息,请参阅“幻行”。

READ COMMITTED隔离级别仅支持基于行的binlog

如果将READ COMMITTEDbinlog_format=MIXED一起使用,则服务器会自动使用基于行的日志记录

使用READ COMMITTED还有其他效果:

对于UPDATEDELETE语句,InnoDB只为更新删除的行保留锁

MySQL评估WHERE条件后,将释放不匹配行的行锁。这大大降低了死锁的概率,但它们仍然可能发生。

对于UPDATE语句,如果一行已经被锁定,InnoDB会执行“半一致”读取,将最新提交的版本返回给MySQL,以便MySQL可以确定该行是否符合UPDATE的WHERE条件。如果行匹配(必须更新),MySQL会再次读取该行,这一次InnoDB要么锁定它,要么等待锁定。

考虑以下示例,从下表开始:

CREATE TABLE t (a INT NOT NULL, b INT) ENGINE = InnoDB;
INSERT INTO t VALUES (1,2),(2,3),(3,2),(4,3),(5,2);
COMMIT;

在这种情况下,表没有索引,因此搜索和索引扫描使用隐藏的聚集索引来锁定记录

(请参见“聚集索引和辅助索引”),而不是索引列。

【MySQL精通之路】Innodb-索引-CSDN博客

假设一个会话使用以下语句执行UPDATE:

# Session A
START TRANSACTION;
UPDATE t SET b = 5 WHERE b = 3;

还假设第二个会话通过在第一个会话之后执行这些语句来执行UPDATE:

# Session B
UPDATE t SET b = 4 WHERE b = 2;

当InnoDB执行每个UPDATE时,它首先为每一行获取一个互斥锁,然后决定是否修改它。

如果InnoDB不修改行,它就会释放锁。

否则,InnoDB将保留锁,直到事务结束。这会对事务处理产生以下影响。

当使用默认的REPEATABLE READ隔离级别时,第一个UPDATE会在它读取的每一行上获取一个x锁,并且不会释放任何一个:

x-lock(1,2); retain x-lock
x-lock(2,3); update(2,3) to (2,5); retain x-lock
x-lock(3,2); retain x-lock
x-lock(4,3); update(4,3) to (4,5); retain x-lock
x-lock(5,2); retain x-lock

第二个UPDATE在尝试获取锁时立即阻塞(因为第一个更新在所有行上都保留了锁),直到第一个UPDATE提交或回滚才继续:

x-lock(1,2); block and wait for first UPDATE to commit or roll back

如果改为使用READ COMMITTED则第一个UPDATE会在其读取的每一行上获取一个x锁,并释放未修改的行的x锁:

x-lock(1,2); unlock(1,2)
x-lock(2,3); update(2,3) to (2,5); retain x-lock
x-lock(3,2); unlock(3,2)
x-lock(4,3); update(4,3) to (4,5); retain x-lock
x-lock(5,2); unlock(5,2)

对于第二个UPDATE,InnoDB进行“半一致”读取,将读取的每一行的最新提交版本返回给MySQL,以便MySQL确定该行是否符合UPDATE的WHERE条件:

x-lock(1,2); update(1,2) to (1,4); retain x-lock
x-lock(2,3); unlock(2,3)
x-lock(3,2); update(3,2) to (3,4); retain x-lock
x-lock(4,3); unlock(4,3)
x-lock(5,2); update(5,2) to (5,4); retain x-lock

但是,如果WHERE条件包括索引列,并且InnoDB使用索引,则在获取和保留行锁时只保留有索引的行。

在下面的示例中,第一个UPDATE在b=2的每一行上获取并保留一个排他写锁,x锁。第二个UPDATE在尝试获取相同记录上的x锁时会阻塞,因为它还使用了在列b上定义的索引。

博主PS:

也就是说,在一个事务里我第一次update会锁住所有的行,update那个字段后,如果这个字段有索引,那么我不会释放行锁,如果这个字段是普通的字段,那么我会释放行锁。

CREATE TABLE t (a INT NOT NULL, b INT, c INT, INDEX (b)) ENGINE = InnoDB;
INSERT INTO t VALUES (1,2,3),(2,2,4);
COMMIT;# Session A
START TRANSACTION;
UPDATE t SET b = 3 WHERE b = 2 AND c = 3;# Session B
UPDATE t SET b = 4 WHERE b = 2 AND c = 4;

READ COMMITTED隔离级别可以在启动时设置,也可以在运行时更改。

在运行时,它可以为所有会话全局设置,也可以为每个会话单独设置。

2.3 读取未提交

SELECT语句以无锁方式执行,但可能会使用行的早期版本。

因此,使用这种隔离级别,这样的读,多次读的数据是不一致的。这也被称为脏读。

此外,此隔离级别的工作方式与READ COMMITTED类似。

2.4 序列化读

这个级别类似于REPEATABLE READ

但InnoDB隐式地将所有纯SELECT语句转换为SELECT……FOR SHARE

(如果禁用了自动提交)。

如果启用了自动提交,SELECT就是一次事务。

因此,它是只读的,如果作为一致(无锁)读取执行,则可以序列化,并且不需要为其他事务阻塞。(如果其他事务已经修改了所选行,要强制阻塞SELECT,请禁用自动提交。

注意:

从MySQL 8.0.22开始,从MySQL 权限表 读取数据(通过联表查询或子查询)但不修改数据的DML操作不会获取MySQL 权限表上的读锁,无论隔离级别如何。有关详细信息,请参阅权限表并发性。

 

 

2.自动提交、提交和回滚

在InnoDB中,所有用户活动都发生在事务内部。

如果启用了自动提交模式,则每条SQL语句将自己形成一个事务。

默认情况下,MySQL在启用自动提交的情况下为每个新连接启动会话,因此,如果每条SQL语句没有返回错误,MySQL会在该语句之后进行提交。

如果语句返回错误,则提交或回滚行为取决于错误。

参见“InnoDB错误处理”。

 

启用了自动提交的会话可以执行多语句事务,方法是以显式START TRANSACTIONBEGIN语句开始,然后以COMMITROLLBACK语句结束。

参见“START TRANSACTION、COMMIT和ROLLBACK语句”。

 

如果在SET autocommit=0的会话中禁用了自动提交模式,则该会话始终使用一个事务。

COMMIT或ROLLBACK语句结束当前事务,并启动新事务。

如果禁用了自动提交的会话在没有显式提交最终事务的情况下被结束了,MySQL将回滚该事务。

有些语句隐式地结束事务,就好像在执行该语句之前执行了COMMIT一样。

有关详细信息,请参阅“导致隐式提交的语句”。

 

COMMIT意味着在当前事务中所做的更改是永久性的,并且对其他会话可见。

另一方面,ROLLBACK语句取消当前事务所做的所有修改

COMMIT和ROLLBACK都会释放在当前事务期间设置的所有InnoDB锁。

Grouping DML Operations with Transactions

2.1 将DML操作以事务分组

        默认情况下,与MySQL服务器的连接从启用自动提交模式开始,该模式会在您执行每一条SQL语句时自动提交。

        如果您有其他数据库系统的经验,这种操作模式可能会不熟悉,因为在其他数据库系统中,标准做法是发送一组DML语句,然后将它们一起提交或回滚。

        要使用多个语句事务,请使用SQL语句SET autocommit=0关闭自动提交,并根据需要使用COMMIT或ROLLBACK结束每个事务。

        若要保留自动提交,请以START TRANSACTION开始每个事务,然后以COMMIT或ROLLBACK结束。以下示例显示了两个事务。第一个是COMMIT;第二个ROLLBACK。

$> mysql test
mysql> CREATE TABLE customer (a INT, b CHAR (20), INDEX (a));
Query OK, 0 rows affected (0.00 sec)
mysql> -- Do a transaction with autocommit turned on.
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO customer VALUES (10, 'Heikki');
Query OK, 1 row affected (0.00 sec)
mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)
mysql> -- Do another transaction with autocommit turned off.
mysql> SET autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO customer VALUES (15, 'John');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO customer VALUES (20, 'Paul');
Query OK, 1 row affected (0.00 sec)
mysql> DELETE FROM customer WHERE b = 'Heikki';
Query OK, 1 row affected (0.00 sec)
mysql> -- Now we undo those last 2 inserts and the delete.
mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM customer;
+------+--------+
| a    | b      |
+------+--------+
|   10 | Heikki |
+------+--------+
1 row in set (0.00 sec)
mysql>

2.2 客户端语言的事务

PHP、PerlDBI、JDBC、ODBC等API或MySQL的标准C调用接口中,您可以像SELECT或INSERT等任何其他SQL语句一样,将COMMIT等事务控制语句作为字符串发送到MySQL服务器。一些API还提供单独的特殊事务提交和回滚功能或方法。

 

3.无锁快照读

快照读意味着InnoDB使用MVCC在某个时间设置数据库的快照。

此事务的查询会看到在此时间点之前提交的事务所做的更改,而不会看到以后或未提交的事务进行的更改

此规则的例外情况是,查询会看到同一事务中前面的语句所做的更改。

此时会导致以下异常:

如果更新表中的某些行,SELECT会看到更新行的最新版本,但也可能会看到任何行的旧版本。

如果其他会话同时更新同一个表,则异常意味着您可能会看到该表从未存在过的状态。

PS:上面说的是读提交。


如果事务隔离级别为REPEATABLE READ(默认级别),则同一事务中的所有快照读都会读取该事务中第一次的快照读。通过提交当前事务,然后发出新的查询,可以为查询获取更新的快照。

使用READ COMMITTED隔离级别,事务中的每个快照读都会设置并读取自己的新快照。

快照读是InnoDB在 READ COMMITTED和 REPEATABLE READ隔离级别中处理SELECT语句的默认模式。

一致性读取不会对其访问的表设置任何锁,因此,在对表执行一致性读取的同时,其他会话可以自由修改这些表。

假设您在默认的REPEATABLE READ隔离级别下运行。当您发出快照读(即普通的SELECT语句)时,InnoDB会为您的事务提供一个时间点,根据该时间点来判断你的查询可以看见哪些数据。

如果另一个事务删除了一行并在指定时间点后提交,则不会认为该行已被删除。插入和更新的处理方式类似。

注意:

数据库状态的快照应用于事务中的SELECT语句,而不一定应用于DML语句

如果插入或修改某些行,然后提交该事务,则从另一个并发的REPEATABLE READ事务发出的DELETEUPDATE语句可能会影响那些刚刚提交的行,即使会话无法查询它们。如果事务确实更新或删除了由其他事务提交的行,则这些更改对当前事务可见。

例如,您可能会遇到以下情况:

SELECT COUNT(c1) FROM t1 WHERE c1 = 'xyz';
-- Returns 0: no rows match.
DELETE FROM t1 WHERE c1 = 'xyz';
-- Deletes several rows recently committed by other transaction.SELECT COUNT(c2) FROM t1 WHERE c2 = 'abc';
-- Returns 0: no rows match.
UPDATE t1 SET c2 = 'cba' WHERE c2 = 'abc';
-- Affects 10 rows: another txn just committed 10 rows with 'abc' values.
SELECT COUNT(c2) FROM t1 WHERE c2 = 'cba';
-- Returns 10: this txn can now see the rows it just updated.

 

您可以通过执行另一个SELECTSTART TRANSACTION WITH CONSISTENT SNAPSHOT且提交事务来更新时间点。

这被称为多版本并发控制。

在下面的示例中,会话A只有在B提交了插入并且A也提交了插入才看到由B插入的行,因此时间点提前到B的提交之后

             Session A              Session BSET autocommit=0;      SET autocommit=0;
time
|          SELECT * FROM t;
|          empty set
|                                 INSERT INTO t VALUES (1, 2);
|
v          SELECT * FROM t;empty setCOMMIT;SELECT * FROM t;empty setCOMMIT;SELECT * FROM t;---------------------|    1    |    2    |---------------------

如果您想查看数据库的“最新”状态,请使用READ COMMITTED隔离级别锁读取

SELECT * FROM t FOR SHARE;

使用READ COMMITTED隔离级别,事务中的每个快照读都会设置并读取自己的新快照

对于FOR SHARE,将发生锁定读取:SELECT将阻塞,直到包含最新行的事务结束

(请参阅“锁读取”)

快照读对某些DDL语句无效:

 

快照读不适用于DROP TABLE,因为MySQL无法使用已删除的表,而InnoDB会破坏该表。

快照读不适用于生成原始表的临时副本并在生成临时副本时删除原始表的ALTER TABLE操作。在事务中重新发出一致读取时,新表中的行不可见,因为在获取事务的快照时这些行不存在。在这种情况下,事务返回错误:ER_TABLE_DEF_CHANGED,“表定义已更改,请重试事务”。

快照读的类型随着查询语句变化而变化,比如

INSERT INTO ... SELECT, UPDATE ... (SELECT)

CREATE TABLE ... SELECT 不指定 FOR UPDATEFOR SHARE:

默认情况下,InnoDB对这些语句使用更强的锁,SELECT部分的行为类似于READ COMMITTED,其中每个快照读即使在同一事务中,也会设置和读取自己的新快照。

在这种情况下,要执行无锁快照读,请将事务的隔离级别设置为READ UNCOMMITTEDREAD COMMITTED,以避免设置行锁。

 

4.锁读取

如果查询数据时在同一事务中插入更新相关数据,则常规SELECT语句无法提供足够的保护。

其他事务可以更新删除您刚才查询的同一行

InnoDB支持两种类型的锁定读取,提供额外的安全性:

 

4.1 SELECT ... FOR SHARE

在读取的任何行上设置共享模式锁定。其他会话可以读取这些行,但在事务提交之前不能修改它们。如果这些行中的任何一行被另一个尚未提交的事务更改,则查询将等待该事务结束,然后使用最新的值。

注意:

SELECT ... FOR SHARE 是 SELECT ... LOCK IN SHARE MODE的替代品。但LOCK IN SHARE MODE任然可用。这些语句是等效的。

但是,FOR SHARE支持OF table_nameNOWAITSKIP LOCKED选项。

请参阅

使用NOWAIT和SKIP LOCKED锁定读取并发。

MySQL 8.0.22之前,SELECT。。。FOR SHARE需要SELECT权限和至少一个DELETE、LOCK TABLES或UPDATE权限。

从MySQL 8.0.22开始,只需要SELECT权限。

从MySQL 8.0.22,SELECT。。。FOR SHARE语句不会获取MySQL 权限表上的读锁。

有关详细信息,请参阅权限表并发性。

 

4.2 SELECT ... FOR UPDATE

对于查询到的行记录,会锁住行和任何关联的索引数据,就像为这些行发出UPDATE语句一样。

 

其他事务被阻止更新这些行、执行SELECT。。。FOR SHARE,或读取某些事务隔离级别的数据。

快照读将忽略在快照中记录上的任何锁。(记录的旧版本无法锁定;它们是通过在记录的内存副本上应用撤消日志来重建的。)

SELECT ... FOR UPDATE需要SELECT权限和至少一个DELETELOCK TABLESUPDATE权限

当事务被提交或回滚时,FOR SHARE和FOR UPDATE查询设置的所有锁都会被释放。

注意:

只有在禁用自动提交时(通过START transaction开始事务或将自动提交设置为0),才可以锁定读取。

 

外部语句中的加锁读不会锁定嵌套子查询中表的行,除非在子查询中也指定了加锁读子句。

例如,以下语句不会锁定表t2中的行。

SELECT * FROM t1 WHERE c1 = (SELECT c1 FROM t2) FOR UPDATE;

要锁定表t2中的行,请向子查询添加一个锁定读取子句:

SELECT * FROM t1 WHERE c1 = (SELECT c1 FROM t2 FOR UPDATE) FOR UPDATE;

4.3 加锁读示例

假设要将新行插入到表的child表中,并确保该child行在parent表中具有父行。您的应用程序代码可以确保整个操作序列中的引用完整性

首先,使用一快照读来查询表PARENT,并验证父行是否存在。您能安全地将子行插入到表child中吗?

不可以,因为其他会话可能会在SELECT和INSERT之间删除父行,而您不会意识到这一点。

要避免此潜在问题,请使用FOR SHARE执行查询

SELECT * FROM parent WHERE NAME = 'Jones' FOR SHARE;

 在FOR SHARE查询返回父“Jones”之后,可以安全地将子记录添加到child表并提交事务。

任何试图在PARENT表中的对应行中获取独占锁的事务都会等待,直到完成,也就是说,直到所有表中的数据处于一致状态。

例如,考虑表CHILD_CODE中的一个整数计数器字段,该字段用于为添加到表CHILD的每个子项分配唯一标识符。不要使用一致读取或共享模式读取来读取计数器的当前值,因为数据库的两个用户可能会看到计数器的相同值,如果两个事务试图将具有相同标识符的行添加到CHILD表中,则会出现重复键错误

这里,FOR SHARE不是一个好的解决方案,因为如果两个用户同时读取计数器,那么当它试图更新计数器时,至少其中一个用户会陷入死锁。

要实现计数器的读取和递增,首先使用FOR UPDATE执行计数器的锁定读取,然后递增计数器。例如:

SELECT counter_field FROM child_codes FOR UPDATE;
UPDATE child_codes SET counter_field = counter_field + 1;

SELECT ... FOR UPDATE读取最新的可用数据,对它读取的每一行设置独占锁。因此,它设置了UPDATE语句将在行上设置的相同的锁。

前面的描述只是SELECT。。。FOR UPDATE有效。

在MySQL中,生成唯一标识符的具体任务实际上只需对表进行一次访问即可完成

UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field + 1);
SELECT LAST_INSERT_ID();

 SELECT语句仅检索标识符信息(特定于当前连接)。它不访问任何表。

5 使用NOWAIT和SKIP LOCKED实现加锁读并发

        如果某一行被事务锁定,则SELECT ... FOR UPDATE 或SELECT ... FOR SHARE事务必须等待直到其他释放行锁。此行为防止其他更新删除行事务。

但是,如果您希望查询到行被锁定时立即返回,或者如果可以从结果集中排除锁定的行则无需等待行锁定被释放。

为了避免等待其他事务释放行锁,NOWAITSKIP LOCKED选项可以与SELECT ... FOR UPDATESELECT ... FOR SHARE 加锁读语句一起使用。

NOWAIT

使用NOWAIT的加锁读从不等待获取行锁。查询会立即执行,如果请求的行被锁定,则会失败并返回错误。

SKIP LOCKED

使用SKIP LOCKED的加锁读从不等待获取行锁。查询立即执行,从结果集中删除锁定的行。

NOWAIT和SKIP LOCKED仅适用于行级锁。

使用NOWAIT或SKIP LOCKED的语句对于基于语句的复制是不安全的。

以下示例演示NOWAIT和SKIP LOCKED。

会话1启动一个事务,该事务对单个记录加行锁。

会话2尝试使用NOWAIT选项对同一记录进行加锁读。

因为请求的行被会话1锁定,所以加锁读会立即返回并返回一个错误。

在会话3中,使用SKIP LOCKED进行的加锁读返回请求的行,但会话1锁定的行除外。

# Session 1:mysql> CREATE TABLE t (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;mysql> INSERT INTO t (i) VALUES(1),(2),(3);mysql> START TRANSACTION;mysql> SELECT * FROM t WHERE i = 2 FOR UPDATE;
+---+
| i |
+---+
| 2 |
+---+# Session 2:mysql> START TRANSACTION;mysql> SELECT * FROM t WHERE i = 2 FOR UPDATE NOWAIT;
ERROR 3572 (HY000): Do not wait for lock.# Session 3:mysql> START TRANSACTION;mysql> SELECT * FROM t FOR UPDATE SKIP LOCKED;
+---+
| i |
+---+
| 1 |
| 3 |
+---+

 

 

 

相关文章:

【MySQL精通之路】InnoDB(7)-锁和事务模型(2)-事务模型

主博客: 【MySQL精通之路】InnoDB(7)-锁和事务模型-CSDN博客 上一篇: 【MySQL精通之路】InnoDB(7)-锁和事务模型(1)-锁-CSDN博客 下一篇: 目录 1.事务隔离级别 2.1 可重复读 2.2 读已提交 2.3 读取未提交 2.4 序列化读 2.自动提交、…...

python中的可哈希和不可哈希

python 中的每一个对象都有一个哈希值,哈希值是一个固定长度的整数,它通常用于快速比较对象的相等性。 如果在对象的生命周期里该对象的哈希值从未改变,那么这个对象是可哈希的(hashable),也称为不可变的。…...

docker命令详解大全

Docker是一种流行的容器化平台,用于快速部署应用程序并管理容器的生命周期。以下是一些常用的Docker命令及其用途的概述: docker run:创建一个新容器并运行一个命令。docker ps:列出当前运行的容器。docker stop:停止…...

体检系统商业源码,C/S架构的医院体检系统源码,大型健康体检中心管理系统源码

体检系统商业源码,C/S架构的医院体检系统源码,大型健康体检中心管理系统源码 体检信息管理系统软件是对医院体检中心进行系统化和规范化的管理。系统从检前,检中,检后整个业务流程提供标准化以及精细化的解决方案。实现体检业务市…...

Vue CLI 的服务介绍与使用(2024-05-20)

1、介绍 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供: 通过 vue/cli 实现的交互式的项目脚手架。 通过 vue/cli vue/cli-service-global 实现的零配置原型开发。 一个运行时依赖 (vue/cli-service),该依赖: 可升级…...

java连接ldap实现查询

文章目录 一、项目背景二、准备工作三、验证结果四、易错点讲解易错点1:java: 无法访问org.springframework.ldap.core.LdapTemplate易错点2:java: 无法访问org.springframework.context.ConfigurableApplicationContext易错点3:[LDAP: error…...

openjudge_2.5基本算法之搜索_2990:符号三角形

题目 2990:符号三角形 总时间限制: 1000ms 内存限制: 65536kB 描述 符号三角形的第1行有n个由“”和”-“组成的符号 ,以后每行符号比上行少1个,2个同号下面是”“,2个异号下面是”-“ 。计算有多少个不同的符号三角形,使其所含”…...

springboot错误

错误总结 1、使用IDEA 的 initialalzer显示2、IDEA 新建文件 没有 java class3、java: 错误: 不支持发行版本 22解决方法4、IDEA-SpringBoot项目yml配置文件不自动提示解决办法 1、使用IDEA 的 initialalzer显示 IDEA创建SpringBoot项目时出现:Initialization fail…...

linux的用户管理

新建用户:1.useradd 2.passwd 完成的操作: (1)/etc/passwd添加一行 (2)/etc/shadow添加一行 (3)/etc/group添加一行 (4)创建用户家目录 (5)创建用户邮件文件 例:创建用户jerry,要求: uid:777&am…...

数美滑块研究

周一,在清晨的阳光照耀下,逆向山脚下的小镇宁静而安详。居民们忙碌地开始一天的生活,而在爬虫镇子的边缘,一座古朴的道观显得格外神秘。 阿羊正静静地坐在青石长凳上,摸鱼养神。突然,一道清脆的声音在他耳…...

【GESP试卷】2024年03月Scratch四级试卷

2024年GESP03月认证Scratch四级试卷 分数:100 题数:27 一、单选题(共15题,每题2分,共30分) 010203040506070809101112131415CDBBACBCDCDADBA 1、小杨的父母最近刚刚给他买了一块华为手表,他说手表上跑的是鸿蒙&…...

每日一题《leetcode--398.随机数索引》

https://leetcode.cn/problems/random-pick-index/ 根据题目所知,所给的数组中有重复的元素。让我们随机输出给定的目标数字的下标索引。 typedef struct {int *sum;int length; } Solution;Solution* solutionCreate(int* nums, int numsSize) {Solution* obj (So…...

【MySQL精通之路】MySQL的使用(9)-设置环境变量

可以在命令提示符下设置环境变量,以影响命令处理器的当前调用,也可以永久设置环境变量以影响未来的调用。 要永久设置变量,可以在启动文件中进行设置,也可以使用系统为此提供的接口进行设置。 有关具体细节,请参阅命…...

JDBC(Java DataBase Connectivity)Java数据库连接

JDBC(Java DataBase Connectivity) Java 语言连接数据库 再本模块中,java提供里一组用于连接数据库的类和接口Java 语言开发者,本身没有提供如何具体连接数据库的功能只是定义了一组java程序连接数据库的访问接口 连接到数据库向数据库发送增,修改,删除这一类的sql发送查询sq…...

1.Redis之初识Redis分布式系统

1.初识Redis 1.1 官网 Redis中文网 Redis 教程 | 菜鸟教程 (runoob.com) 1.2 解释 在内存中存储数据 定义变量,不就是在内存中存储数据嘛?? Redis 是在分布式系统(进程的隔离性:Redis 就是基于网络,可以把自己内存中的变量给别的进程…...

基于SpringBoot的网盘系统设计与实现

第1章 绪论... 1 1.1 研究背景与意义... 1 1.1.1 研究背景... 1 1.1.1 研究意义... 1 1.2 国内外研究现状... 2 1.2.1 国内研究现状... 2 1.2.2 国外研究现状... 3 1.3 论文组织架构... 4 第2章 关键技术介绍... 5 2.1 SpringBoot. 5 2.2 MySQL数据库... 5 2.3 MVC架…...

【C++初阶】vector

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ 🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿&#x1…...

elasticsearch 和 RediSerch

elasticsearch 和 RediSerch 前情提要 学习文章来自Docker 安装 ElasticSearch - 知乎 (zhihu.com) docker 安装 docker pull docker.io/elasticsearch:7.1.1启动! docker run -d --name es -p 9200:9200 -p 9300:9300 -e "discovery.typesingle-node" b0e9f9f0…...

删除MySQL中所有表的外键

方法一: 原理 查询schema中所有外键名称然后拼接生成删除语句 第一步: SELECT CONCAT(ALTER TABLE ,TABLE_SCHEMA,.,TABLE_NAME, DROP FOREIGN KEY ,CONSTRAINT_NAME, ;) FROM information_schema.TABLE_CONSTRAINTS c WHERE c.TABLE_SCHEMA数据库名…...

webstorm新建vue项目相关问题

前言 这个迭代后端需求偏少,前端code的键盘都起火星子了。来了4个外包支持,1个后端3个前端,还是不够用啊。刚好趁这个机会稍微学习下vue,其实之前环境也配置过了,所以这里就不分享环境配置了,主要分享下新建…...

全面解析:npm 命令、package.json 结构与 Vite 详解

全面解析:npm 命令、package.json 结构与 Vite 详解 一、npm run dev 和 npm run build 命令解析 1. npm run dev 作用:启动开发服务器,用于本地开发原理: 启动 Vite 开发服务器提供实时热更新(HMR)功能…...

使用多Agent进行海报生成的技术方案及评估套件-P2P、paper2poster

最近字节、滑铁卢大学相关团队同时放出了他们使用Agent进行海报生成的技术方案,P2P和Paper2Poster,传统方案如类似ppt生成等思路,基本上采用固定的模版,提取相关的关键元素进行模版填充,因此,海报生成的质量…...

react库:class-variance-authority

文章目录 前言一、cva 的核心作用二、代码逐层解析参数详解基础样式(第一个参数):variant:定义颜色/风格变体(如 default、destructive)。size:定义尺寸变体(如 sm、lg)。…...

Splunk Validated Architecture (SVA):构建企业级可观测性与安全的基石

Splunk Validated Architecture (SVA) 是 Splunk 官方提供的一套经过严格测试、性能验证和最佳实践指导的参考架构蓝图。它并非单一固定方案,而是根据企业数据规模、性能需求、高可用性目标和合规要求,提供一系列可落地的部署模型。SVA 的核心价值在于为…...

关于用Cloudflare的Zero Trust实现绕过备案访问国内站点说明

cloudflare 是一个可免费的CDN,CDN(Content Delivery Network,内容分发网络)加速国内网站,通常是已备案的。Zero Trust类似FRP,可以将请求转发到目标服务器。在使用Zero Trust绕过备案访问国内网站需要&…...

华为计试——刷题

判断两个IP是否属于同一子网 题目:给定一个子网掩码和两个 IP 地址,判断这两个 IP 地址是否在同一个子网中。 思路:首先,判断这个 IP 地址和子网掩码格式是否正确,不正确输出 ‘1’,进而结束;…...

后端项目中静态文案国际化语言包构建选型

这是一个很关键的问题。在做国际化(i18n)时,不同语言包格式如 .resx、.properties 和 .json 都可用,但各自有适用场景、特性与限制,你在选择时可以根据你的开发语言、生态和维护成本权衡。 ✅ 一张对比表:.…...

算法打卡第11天

36.有效的括号 (力扣20题) 示例 1: **输入:**s “()” **输出:**true 示例 2: **输入:**s “()[]{}” **输出:**true 示例 3: **输入:**s “(]”…...

单元测试报错

报错信息如下所示: 五月 30, 2025 5:35:44 下午 org.junit.vintage.engine.descriptor.RunnerTestDescriptor warnAboutUnfilterableRunner 警告: Runner org.junit.internal.runners.ErrorReportingRunner (used on class redis.demo.RedisTemplateTest) does not…...

科学智能赋能空间科学研究(2):AI4S 范式下空间科学实验的核心挑战

中国科学院空间应用工程与技术中心在空间科学实验领域的研究覆盖了多模态空间科学实验数据模式挖掘、领域知识抽取、跨学科知识融合与认知智能等研究内容,有效促进了空间科学实验领域的数据应用生态的体系化建设,相关研究成果已正式发表于权威学术期刊《…...