SQL入门经典(十) 之事务
事务是什么?事务关键在与其原子性。原子性概念是指可以把一些事情当作一个执行单元来看待。从数据库角度看待。他是指应该全部执行或者全部不执行一条或多条语句的最小组合。当处理数据时候经常确保一件事发生另一件事也随之发生。或者二件事都不发生。实际上可能达到程度是有几十件事情或者更多的事情都必须一起发生或者都不发生。来看一个一个经典事例。这个事例各大书籍讲事务都有。就是你去银行转帐给朋友。转了100元sql如下:你的帐号扣了100元,你朋友帐号加了100元。看起来很完美。其实有个BUG存在,你的帐号被扣100元后在执行你朋友帐号加100元时候,数据出现错误,没有添加进去。
ACID事务
如果你的系统被设计为使用ACID事务,则不会出现上面那种情况。ACID事务
1.原子性:事务会全部执行,要么全部不执行。
2.一致性:需要遵循所有约束以及其他数据库完整性规则,并且完全的更新所有相关的对象(数据和索引页)
3.隔离性:每一个事务与其他任何事务完全的隔离。一个事务动作不会受其它事务动作干扰。
4.持久性:完成事务后,它的作用结果永久保存在系统内部。数据是“安全的”。这是指不会在停电或者系统故障或设备故障不会导致数据写入一半的情况发生。
事务简单操作简介
你需要一种办法确保第一条SQL语句执行,第二条也跟着执行。实际上不存在这样一种可完全控制可能。从硬件故障到违反数据完整性规则简单事情。都有可能发生错误。然而幸运的是;有一种可能达到相同的目地方法-基本忘记从前发生什么事。至少可以强制这个概念:如果某件事没有发生,那什么不会发生,至少事务的作用范围内部就是这样。
如何标志标志是开始和结束,回滚
BEGIN TRAN : 设置为起点
COMMIT TRAN :让事务成为数据中心永久的,不可逆的一部分
ROLLBACK TRAN:不考虑所有更改,本质上想说忘记以前发生的一却
SAVE TRAN:创建一个特定标识符,只允许部分回滚
BEGIN TRAN 事务开始很好理解,它唯一目的就是表示一个执行单元开始。高级部分不讨论了,因为面向DBA的高级特性。
COMMIT TRAN 提交事务一个终点,当发出COMMIT TRAN命令时候,可以认为该事务是持久性
ROLLBACK TRAN 每当考虑ROLLBACK TRAN 时候表示。表示该执行单元有错误。或者回到起点重新开始。(忘记过去,重新开始)
SAVE TRAN 保存事务创建书签。创建书签在数据回滚时候,回滚到每个书签上。记住ROLLBACK在回滚会清除所有书签。如果保存了5个书签,一旦执行ROLLBACK,5个书签全部清空。
试一试事务:
我朋友在帮市公安局做数据维护,因为数据库不安全。经常被黑客攻击在一些标题加入跳转HTML代码。我朋友每隔一段时间就清除一下HTML代码,突然有一天我朋友sql写错了。替换之后有个表字段值被清空,马上使用备份,备份文件和现在文件相差一个月。因为服务器备份出错了。一个月没有备份不知道。最后通过省公安局备份数据还原那个字段的值。如果使用事务,发现不对,可以回滚。我们接着事务先看SQL语句和结果看事务有什么神奇之处。
USE panda --继续用这个数据库 GO SELECT * FROM dbo.test002 --结果集合 --4 122 22 xxx@qq.com 112 --6 122 22 x22xx@qq.com 31222 --12 231 3334 qxxfs@qq.com 18612345678 BEGIN TRAN UPDATE dbo.test002 SET name='test' --本来修改ID 为12的数据。忘记写WHERE 过滤了 SELECT * FROM dbo.test002 --结果集合 --4 test 22 xxx@qq.com 112 --6 test 22 x22xx@qq.com 31222 --12 test 3334 qxxfs@qq.com 18612345678 --在查询一次 表示我误伤了所有数据。 那就进行回滚: ROLLBACK TRAN SELECT * FROM dbo.test002 --结果集合 --4 122 22 xxx@qq.com 112 --6 122 22 x22xx@qq.com 31222 --12 231 3334 qxxfs@qq.com 18612345678 数据正常了
如果多条语句呢?如下图
BEGIN TRAN UPDATE dbo.test002 SET name='test' begin TRAN UPDATE dbo.test003 SET name='test' ROLLBACK TRAN --这条语句执行后,前面2条事务语句全部回滚。 COMMIT TRAN --数据会更新完毕。
数据脏读:我执行BEGIN TRAN UPDATE dbo.test002 SET name='test' ,有些人胆子大来获取数据,我在ROLLBACK STRN些,那他就倒霉了,这就脏读。。。
非重复读取:非重复度很容易跟脏读混淆。只知道这个术语就可以了。
幻读:只是在偶然的机会会出现。很少会出现。它在运行更新语句的时候,有人执行添加语句。
丢失更新:说的事例,你经理在看某个员工的工资表时候。员工A可以加工资了。你把员工A的工资从5000上调5500了。人事部B也在看A的信息。只是修改A的人事信息。在同时更新时候覆盖了事务1.
接着SQL入门经典(九)的视图:
说些@@EERROR这个系统错误号。
先看SQL语句在一句句解释
declare @count int ; set @count=0; BEGIN TRAN UPDATE dbo.test003 set name='test' where ID=4 select @count=@count+@@ERROR; INSERT dbo.test003 VALUES(15,GETDATE(),'TEST_5')--这条语句会失败@@ERROR这个值会>0 select @count=@count+@@ERROR; if(@count>0) ROLLBACK TRAN ELSE COMMIT TRAN --(0 行受影响) 说明@@ERROR是个错误号。如果发生错误就是>0的数字
TRY CATCH 看下面SQL语句
BEGIN TRY --TRY 开始 BEGIN TRAN UPDATE dbo.test003 set name='test' where ID=4 INSERT dbo.test003 VALUES(15,GETDATE(),'TEST_5') COMMIT TRAN END TRY --TRY结束 BEGIN CATCH --如果TRY 发生错误就执行这里面语句 ROLLBACK TRAN END CATCH --这句代码执行结果是(0 行受影响)说明COMMIT TRAN 没有执行。执行了ROLLBACK TRAN -- INSERT dbo.test003 VALUES(15,GETDATE(),'TEST_5') -- 改为 --INSERT dbo.test003 VALUES(2,GETDATE(),'TEST_5') --(2行受影响)TRY里面没有错误,就执行COMMIT TRAN不会执行CATCH里的代码