sec*_*age 0 sql-server t-sql transaction transaction-log checkpoint
我的课本上说:
从您开始事务时开始,您的更改与其他用户隔离。您正在做的事情只有您自己可以看到,并且在您 COMMIT 之前不会真正完成——尽管在您看来是真实的,但只有您才能看到结果。任何其他试图查看的人,他们都可以看到旧值,或者如果他们大胆,他们可能会得到脏读。
我很困惑,所以我将使用下面的图片提出一些问题:
和 t-sql 代码是
BEGIN TRAN
UPDATE checking
SET Balance = Balance - 1000
WHERE Account = 'Sally' // original balance is 2000
--------------a checkpoint occurs ---------
UPDATE savings
SET Balance = Balance + 1000
WHERE Account = 'Sally'
COMMIT TRAN
Run Code Online (Sandbox Code Playgroud)
并且我们知道,只有在执行了“COMMIT TRAN”之后,才会在日志缓冲区中创建描述 COMMIT 的新日志记录。
Q1- 为什么在 COMMIT 之前结果只对我可见? 假设在检查 sally 为负 -1000 后发生检查点,并且更新的记录位于第 4 页(内存中),因为它尚未提交,因此不会有日志记录日志缓冲区,因此磁盘(.ldf)中不会有相应的日志记录,但缓存第4页将写入磁盘(.mdf),因此任何用户都可以看到该记录的最新更改?
Q2-这种情况下事务控制如何保持原子性?
正如我所讨论的,当检查点发生时,第 4 页(在缓存中,包含记录的最新余额值:1000)将被写入磁盘,如果出现系统故障立即。SQL server重启后,.ldf文件中没有日志记录,如何知道如何将记录的余额(当前为1000)恢复到原来的值(余额为2000)?
关于可见性,SQL Server 使用锁定和/或行版本控制来实现隔离级别。更改始终对当前会话可见。未提交的更改对其他会话可见,只有他们正在使用UNCOMMITTED(“他们可能会被脏读”)。通常,其他会话将被阻止(由于锁定)或将在更改之前(由于行版本控制)看到原始值,直到提交事务。
事务隔离级别及其实现与事务持久性无关。日志和数据文件写入何时发生对于隔离级别是否正常运行并不重要。
为了保证持久性和原子性,日志记录总是在相应的数据文件之前写入日志。重要的是,这包括未提交和已提交事务的更改。这种预写日志允许 SQL Server 前滚所有事务,然后在恢复期间以及ROLLBACK执行a 时回滚未提交的事务。
| 归档时间: |
|
| 查看次数: |
119 次 |
| 最近记录: |