(1)原子性:(ATOMIC) 整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节
(2)一致性(Consistency)在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
(3)隔离性(Isolation)两个事务的执行是互不干扰的,一个事务不可能看到其他事务运行时中间某一时刻的数据
(4)持久性(Durability)在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
自动提交事务:每条单独语句就是一个事务
隐式事务:前一个事务完成时新事物隐式启动,每个事务仍以COMMIT或ROLLBACK语句显示结束
分布式事务:跨越多个服务期盼的事务
事务管理的常用语句:
BEGIN TRANSACTION:建立一个事务
COMMIT TRANSACTION:提交事务
ROLLBACK TRANSACTION:事务失败时执行回滚操作
SAVE TRANSACTION:保存事务
设置事务隔离级别
SET TRANSACTION ISOLATION LEVEL
{
READ UNCOMMITTED
| READ COMMITTED
| REPEATABLE READ
| SNAPSHOT
| SERIALIZABLE
} [ ; ]
READ UNCOMMITTED级别:该级别不隔离数据,即使事务正在使用数据,其它事务也能同时修改或删除该数据。在该级别运行的事物,不会发出共享锁来防止其他事务修改当前事务读取的数据。
READ COMMITTED级别:指定语句不能读取已由其他事务修改但未提交数据,这样可以避免脏读。其他事务可以在当前事务各个语句之间更改数据,从而产生不可重复读取或幻象数据。在该事务中读取的数据随时都可能修改,但已经修改过的数据事务会一直被锁定,直到事务结束为止。该选项为SQL Server默认设置。
REPEATABLE READ级别:指定语句不能读取已由其他事务修改但尚未提交的行,并且指定,其他任何事务都不能在当前事务完成之前修改由当前事务读取的数据。该事务中的每个语句所读取的全部数据都设置了共享锁,并且该共享锁一直保持到事务完成为止。这样可以防止其他事务修改当前事务读取的任何行。
SNAPSHOT级别:指定事务中任何语句读取的数据都将是在事务开始时便存在的数据的事务上一致的版本。事务只能识别在其开始之前提交的数据修改。在当前事务中执行的语句将看不到在当前事务开始以后由其他事务所做的数据修改。其效果就像事务中的语句获得了已提交数据的快照,因为该数据在事务开始就存在。
除非正在恢复数据库,否则SNAPSHOT事务不会在读取数据时请求锁。读取数据的SNAPSHOT事务不会阻止其他事务写入数据。写入数据的事务也不会阻止SNAPSHOT事务读取数据。
SERIALIZABLE级别:将事务所要用到的时间全部锁定,不允许其他事务添加、修改和删除数据,使用该等级的事务并发性最低,要读取同一数据的事务必须排队等待。
BEGIN TRANSACTION
INSERT INTO animals VALUES('1','dog',null,null,10,null,null)
SELECT @animalsCount INT
set @animalsCount = (SELECT COUNT(*) FROM animals)
IF @animalsCount>5
BEGIN
ROLLBACK TRANSACTION
PRINT '插入数据太多,插入失败!'
END
ELSE
BEGIN
COMMIT TRANSACTION
PRINT '插入成功!'
END
2.锁
SQL Server支持多用户共享同一数据库,但是多用户对同一数据库进行修改时会产生并发问题,使用锁可以解决该问题。
数据库中数据的并发操作经常发生,而对数据的并发操作会带来下面一些问题:脏读、幻读、非重复性读取、丢失更新。
锁可以锁定的资源,由颗粒大小分为6种可锁定的资源,这些资源由粗到细分别是:
数据库、表、区段页(一组连续的8个数据页)、页、键、行
锁得类型:更新锁、排它锁、共享锁、键范围锁、架构锁
死锁
在两个或多个任务中,若果每个任务锁定了其他事务试图锁定的资源,会造成这些任务永久阻塞,从而出现死锁。
1.死锁的原因
形成死锁的4个必要条件:
(1)请求与保持条件:获取资源的进程可以同时申请新的资源
(2)非剥夺条件:已经分配的资源不能从进程剥夺
(3)循环等待条件:多个进程构成环路,并且其中每个进程都在等待相邻进程正占用的资源
(4)互斥条件资源只能被一个进程使用
锁的应用案例
1.锁定行
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FFROM ID='1' ROWLOCK WHERE ID='2'
2.锁定数据表记录
SELECT Food FROM animals TABLELOCKX WHERE Food=1
3.排它锁
BEGIN TRANSACTION transaction1
UPDATE animals SET Cost=20 WHERE ID='2';
WAITFOR DELAY '00:00:10';
COMMIT TRAN
BEGIN TRAN transaction2
SELECT * FROM animals WHERE ID='2';
COMMIT TRAN
4.共享锁
BEGIN TRAN transaction1
SELECT ID,name,age FROM animals WITH(HOLDLOCK) WHERE ID='2';
WAITFOR DELAY '00:00:10';
COMMIT TRAN
BEGIN TRAN transaction2
SELECT * FROM animals WHERE ID='2';
COMMIT TRAN