事务方面的有点不太理解, 知道的来看哈吧
事务是单个的工作单元。如果某一事务成功,则在该事务中进行的所有数据更改均会
提交,成为数据库中的永久组成部分。如果事务遇到错误且必须取消或回滚,则所有
数据更改均被清除
这个是网上的说法, 中间有一个地方不是很理解 , 也是刚好和最近一直在寻找的一个东西很相似
针对: 所有数据更改均被清除, 请问 在提交事务之前, 会对那些SQL语句 会单个的 执行操作么? 就是不太清楚在提交之前到底是把这些SQL语句进行了什么操作?
难道是提交的时候才执行?
还有就是所有的数据更改会清除, 难道SQL 的数据可以撤销之前执行的SQL 语句的执行么?
------解决方案--------------------可以撤销。举个例子
:
begin tran
insert tb
select * from test
update tb
set col1 =5
if @error<>0
rollback
else commit
意思就是如果上面的两天雨具正确执行了责提交该事务
否则不提交,回滚。回滚到之前没执行任何语句的状态
------解决方案--------------------事物里面的一系列操操可以被整个提交,就是都执行成功了
如果遇到错误,那么你可以控制其回滚
当然这个错误是要我们认为控制其回滚的
------解决方案--------------------BEGIN TRAN
INSERT [tb](id)SELECT 5
当执行到这里的时候,
事物还没有提交
实际上你的库里面已经插入了这条记录
如果你下面回滚那么这条记录就没了,如果提交了事物,别且提交成功 那么久有了
你可以测试一下,在另一个窗口执行
SELECT * FROM tb
这样查询一直在等待,以为事物的原因这个表被锁定了
说以读取不到记录
可以使用
SELECT * FROM tb WITH(NOLOCK)--不使用锁,这样查到的数据叫做脏读
可以看到记录已经在表里面存在了
------解决方案--------------------配合 日志的作用 来了解这个问题
------解决方案--------------------
事务一般先到日志记录着,也会申请锁资源,除非开启了XACT_ABORT 选项,不然要显式处理(或者由服务器杀掉,否则就会永久堵塞进而成为死锁)。建议显示使用事务,从begin tran开始。
后面的语句一般使用IF @@ERROR <> 0 commit(没错误就提交)else rollback来结束,有些语句比如insert,也可以使用@@rowcount>0(即影响行数大于0)来判断是否插入成功,如果成功就commit,否则rollback。
事务涉及ACID属性,而一切属性也因为原子性(ACID中的A)而产生。为了保证原子性,事务要么全做要么全部做。
无论是否是否提交或者回滚,都会记录在日志中(这里说明一下,无论是简单模型还是大容量日志模式,都会记录日志,日志是不能禁用的)。服务器重启时,会有专门的进程检查日志,然后把commit的东西写入数据文件(这叫前滚),把未提交的事务取消重做(这叫回滚)。来保证数据一致性(ACID中的I)。也就是说如果你的事务未提交然后宕机了。那么就要重做。如果已提交,而日志文件未损坏,那么重启之后就会写入数据文件。保证你的永久性(ACID中的D)。
另外,正常运行的服务器,默认每一分钟会执行一次Checkpoint,把日志中改过且提交的操作(称为脏页)写入数据文件。但不对未提交操作处理。
还有一个进程叫lazy wirter,忘了多久执行一次,一般是在内存处于压力下,才会触发,把一些脏页写入数据文件,然后把内存空闲出来。
以上是记忆中的东西,可能会有少许偏差。但是说明一点,单纯看事务是什么是片面的,就像
6楼说的,要结合日志来看
------解决方案--------------------其实怎么说呢,光说你很难理解的
建议你用软件看日志
------解决方案--------------------提交之前,对数据库的操作都是在内存里进行的,可以这么理解,只有等你食物里的所有代码读执行成功了,执行了提交命令 commit ,才对这些内存里的东西写回硬盘,也就是所说的对数据库进行了写操作。否则如果执行时出错了,那么执行rollback后,那些内存里的东西就释放了,不对数据库写东西。