SqlServer常见的三种事务操作及事务锁死讲解

sql server 常见的三种事务

1.自动提交事务

是sql server 默认的一种事务,每一个sql语句都会被看作一个事务来处理。

2.显示事务

t-sql标明由begin transaction 来开始事务,由commmit transaction来提交事务,rollback transaction 来回滚事务

3.隐试事务

使用set implicit_transactions on 将将隐式事务模式打开,不用begin transaction开启事务,当一个事务结束,这个模式会自动启用下一个事务,只用commit transaction 提交事务、rollback transaction 回滚事务即可。

1) 显试事务的常见操作

1.begin transaction

2.commit transaction

3.rollback transaction

4.save transaction

–测试回滚到保存事务节点的地方

begin tran

begin try

insert into t_his_purchasedetail values (n’1804180000001′, n’030100172′, ’50’, n’030116112000001′, ‘2018-04-18 09:29:53.983’,

n’71e0cdcf-9ed7-7adf-25f2-18bd9bedeb83′, n’0301001039′, ‘1’, n’1804180000001′, n’00011′, ‘0’);

save tran yigjn

insert into t_his_purchasedetail values (n’1804180000002′, n’030100172′, ’50’, n’030116112000001′, ‘2018-04-18 09:29:53.983’,

n’71e0cdcf-9ed7-7adf-25f2-18bd9bedeb83′, n’0301001039′, ‘1’, n’1804180000001′, n’00011′, ‘3’);

insert into t_his_purchasedetail values (n’1804180000003′, n’030100172′, ’50’, n’030116112000001′, ‘2018-04-18 09:29:53.983’,

n’71e0cdcf-9ed7-7adf-25f2-18bd9bedeb83′, n’0301001039′, ‘1’, n’1804180000001′, n’00011′, ‘0’);

end try

begin catch

select error_number(),

error_severity(),

error_state(),

error_procedure(),

error_line(),

error_message()

print(@@trancount);

if (@@trancount > 0)

begin

print(‘yigjn catch’)

rollback tran

end

end catch

if (@@trancount > 0)

begin

print(‘yigjn end’)

rollback tran yigjn

select * from t_his_purchasedetail

end

2) set xact_abort

设置xact_abort on/off 指定是否回滚当前事务 on时如果当前sql出错则回滚整个事务,off时如果sql出错则回滚当前sql语句,其他语句照常写入

~~~~~~~~~需要注意 xact_abort 只对运行时异常有效,如果编译错误则不会启用

— 类型转换错误 会使xact_abort 失效, 溢出整数列可以进行正确回滚

–测试 xact_abort

truncate table t_his_purchasedetail

set xact_abort off

begin tran

insert into t_his_purchasedetail values (n’1804180000001′, n’030100172′, ’50’, n’030116112000001′, ‘2018-04-18 09:29:53.983’,

n’71e0cdcf-9ed7-7adf-25f2-18bd9bedeb83′, n’0301001039′, ‘1’, n’1804180000001′, n’00011′, ‘0’);

save tran yigjn

insert into t_his_purchasedetail values (n’1804180000002′, n’030100172′, ’50’, n’030116112000001′, ‘2018-04-18 09:29:53.983’,

n’71e0cdcf-9ed7-7adf-25f2-18bd9bedeb83′, n’0301001039′, ‘1’, n’1804180000001′, n’00011′, ‘asd’);

insert into t_his_purchasedetail values (n’1804180000003′, n’030100172′, ’50’, n’030116112000001′, ‘2018-04-18 09:29:53.983’,

n’71e0cdcf-9ed7-7adf-25f2-18bd9bedeb83′, n’0301001039′, ‘1’, n’1804180000001′, n’00011′, ‘0’);

commit tran

select * from t_his_purchasedetail

3) 死锁

— 分别将两个代码块放入两个查询界面执行

— 测试事务进程死锁

begin tran

update t_his_purchasedetail set num = ‘1’ –where orderno = ‘1804180000001’

waitfor delay ’00:00:10′

update t_dept set upflag = ‘1’– where fid = ‘0301014’

commit tran

begin tran

update t_dept set upflag = ‘1’ –where fid = ‘0301’

waitfor delay ’00:00:10′

update t_his_purchasedetail set num = ‘1’– where orderno = ‘1804180000003’

commit tran

~~~~~~~~~~~~~~~~~~测试出来锁的粒度为页级锁

4) 锁的分类

从数据库角度来分分为三种: 1. 排他锁(x) 2.共享锁(s) 3.更新锁(u)

5) 死锁的处理

— 查询所占用

select l.request_session_id,

db_name(l.resource_database_id),object_name(p.object_id),

l.resource_description,l.request_type,

l.request_status,request_mode

from sys.dm_tran_locks as l

left join sys.partitions as p

on l.resource_associated_entity_id=p.hobt_id

sql server 自动侦测何时死锁发生,sql server 中有一个独立进程叫做 lock_monitor,大约五秒钟检查一次是否存在死锁

6) 事务隔离级别 https://blog.itpub.net/13651903/viewspace-1082730/

修改事务隔离级别

set transaction isolation level

repeatable read

go

1.read uncommitted

造成的问题 : 脏读 可以读到其他事务未提交的操作 , 幻读, 不可重复度

2.read committed

解决的问题:脏读 ,操作的时候加上了x锁其他事务不可读该数据 问题:幻读 , 不可重读(另一个事务仍可以修改该事务读取的数据)

3.repeatable(重复) read

解决问题 : 不可重复度 (另一个事务无法修改删除该事务读取的数据,只能等该事物结束之后)

3.serializable

解决问题:幻读 (另一个事务无法insert一个事务正在查询的表)

7) 锁粒度

1.database

每个数据库的查询连接都会给数据库加一个s锁

2.d:\program files\sql server2008\mssql10_50.mssqlserver\mssql\backup

–查看锁占用情况

select resource_type,resource_description,request_mode,request_status,request_type,request_lifetime , request_session_id, db_name(resource_database_id)

,resource_associated_entity_id,p.*

–, object_name(resource_associated_entity_id)

from sys.dm_tran_locks l left join sys.partitions p on l.resource_associated_entity_id = p.hobt_id

where resource_database_id=db_id() and request_session_id=@@spid

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐