大家好,我有个问题想请教下:
SQL事务:事务修改但尚未提交数据怎么理解?例如下面的例子:
begin tran
 update Table2 set X=X+1000;
 waitfor delay '00:00:15';
 select * from Table2;
commit tran
代码执行到update Table2 set X=X+1000这个地方不是已经对数据库进行修改了吗,难道这个地方修改还没有提交到数据库,提交到底是什么意思?谢谢大家指点下我的困惑

解决方案 »

  1.   

    事务的任何操作首先会记录到数据库的日志里面,然后当做日志备份、checkpoint、lazywriter等的时候,才会写入到数据库的数据文件中。
    你上面的操作会记录到日志文件中,但是在commit之前,这部分的操作会被标志未未提交,一旦数据库突然发生故障,那么这部分未提交的事务是不会生效的,也就是回滚掉,等于没做过。
      

  2.   

    在帖中再次遇到你-DBA,幸会!
    那我可不可以这样理解:在该例中执行update、select时候相当于先只是在对数据库的日志文件做修改,等执行到commit tran时,把数据库日志文件的相关操作复现到数据库文件去吗?
      

  3.   

    其实操作最开始还是在缓存里面做,然后才到日志文件里面,再做日志备份、checkpoint(默认一分钟自动执行一次)、lazywriter(不定期自动执行)这些操作时,才会写到数据文件,也就是你锁认为的数据库文件里面去。
    一旦commit了,那么日志文件就会标识这部分的操作已经提交,也就是永久性修改。哪怕数据库出故障了,这部分的操作也不会回滚,反而会写入到数据文件中。
      

  4.   

    我结合脏读你帮我理一下思路,谢谢了。脏读:脏读也就是一个用户进程读取了另一个用户进程修改过但没有正式提交的数据。回到这个问题,按这个事务理解,事务在未提交到数据库中去时(未运行到commit tran),数据库文件还未修改,那怎么会产生脏读呢?
      

  5.   

    SQLServer默认隔离级别为:read committed,也就是已提交读,如果启用了快照隔离模式,是可以避免脏读的。我也有点晕了,你还是看看博客吧,暂时我也不敢下什么定论。http://blog.csdn.net/happyflystone/article/details/4604573
      

  6.   

    启动了默认事物处理,然后UPDATE  Table2后,此时没有提交事物 Table2,如果去SELECT  * from Table2系统是不允许脏读数据的。 可以使用select * from table2  with (nolock)读取dirty data  
      

  7.   

    DBA_Huangzj:谢谢你的回答,如果你有更好的建议望给我讲下。我对脏读这个概念感觉模糊,不好理解。
      

  8.   

    ejason:你好,在update表时,在该事务还未结束其他事务是不能select表的,是由于事务还未提交,也就是还未修改数据库文件,只是修改了数据库相关日志文件,如果事务发生回滚的话,数据库表文件将不会修改的。
    回到脏读的话题,脏读dirtyreads:当事务读取还未被提交的数据时,就会发生这种事件。举例来说:Transaction   1   修改了一行数据,然后   Transaction   2   在   Transaction   1   还未提交修改操作之前读取了被修改的行。如果   Transaction   1   回滚了修改操作,那么   Transaction   2   读取的数据就可以看作是从未存在过的。
    问题:既然脏读是在事务未提交时读取数据,而事务未提交没有修改数据库表文件,那脏读是怎么形成的,难道他不直接读表文件,而是先去读数据库日志文件?谢谢你的回答,可能我问的问题有点弱智,再次谢谢
      

  9.   

    DBAXMMDS:你好,那您可以帮我解释这个疑惑不呢?在update表时,在该事务还未结束其他事务是不能select表的,是由于事务还未提交,也就是还未修改数据库文件,只是修改了数据库相关日志文件,如果事务发生回滚的话,数据库表文件将不会修改的。
    回到脏读的话题,脏读dirtyreads:当事务读取还未被提交的数据时,就会发生这种事件。举例来说:Transaction 1 修改了一行数据,然后 Transaction 2 在 Transaction 1 还未提交修改操作之前读取了被修改的行。如果 Transaction 1 回滚了修改操作,那么 Transaction 2 读取的数据就可以看作是从未存在过的。
    问题:既然脏读是在事务未提交时读取数据,而事务未提交没有修改数据库表文件,那脏读是怎么形成的,难道他不直接读表文件,而是先去读数据库日志文件?