事务隔离级别

https://en.wikipedia.org/wiki/Isolation_(database_systems))
https://tech.meituan.com/2014/08/20/innodb-lock.html

隔离级别 脏读(Dirty Read) 不可重复读(NonRepeatable Read) 幻读(Phantom Read)
未提交读(Read uncommitted) 可能 可能 可能
已提交读(Read committed) 不可能 可能 可能
可重复读(Repeatable read) 不可能 不可能 可能
可串行化(Serializable ) 不可能 不可能 不可能
  • 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
  • 提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
  • 可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
  • 串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

不可重复读重点在于update和delete,而幻读的重点在于insert
在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复读了。
但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。
需要Serializable隔离级别 ,读加共享锁,写加排他锁,读写互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。

SQL Server 默认是 Read Committed, 可以视情况加 WITH (NOLOCK) , 使类似于 READ UNCOMMITTED
MySQL 默认是 REPEATABLE READ

设置事务隔离级别:
MySQL https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html
SQL Server https://docs.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql?view=sql-server-ver15

分页写法对比

https://www.w3schools.com/sql/sql_top.asp

SQL Server / MS Access Syntax:
SELECT TOP number|percent column_name(s)
FROM table_name_WHERE _condition;

MySQL Syntax:
SELECT column_name(s)
FROM table_name_WHERE _condition

LIMIT number;
Oracle Syntax:
SELECT column_name(s)
FROM table_name
WHERE ROWNUM <= number;