加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql server事务全攻略(转载)

发布时间:2020-12-12 09:00:19 所属栏目:MsSql教程 来源:网络整理
导读:table id="layoutManager" cellspacing="0" cellpadding="0" tr td id="FullViewNav" style="FONT-SIZE: 10pt"/td td id="MainFocus" style="FONT-SIZE: 10pt" div style="FONT-SIZE: 10pt" div style="FONT-SIZE: 10pt" table cellspacing="0" tr td style=
<tr>
<td id="FullViewNav" style="FONT-SIZE: 10pt"></td>
<td id="MainFocus" style="FONT-SIZE: 10pt"><div style="FONT-SIZE: 10pt">
<div style="FONT-SIZE: 10pt">
<table cellspacing="0">
<tr>
<td style="FONT-SIZE: 10pt">
<ul id="ctl00_MainContentPlaceholder_ctl01_Toolbar_Internal_LeftToolbarList">
</td>
<td style="FONT-SIZE: 10pt" align="right">
<ul id="ctl00_MainContentPlaceholder_ctl01_Toolbar_Internal_RightToolbarList">

  • 单击以查看前 20 项单击以查看后 20 项
  • <div id="entrycns!44A16F22F40F3BC1!205" style="FONT-SIZE: 10pt" bv:cns="cns!44A16F22F40F3BC1!205" bv:ca="true" bv:cat="计算机与 Internet"&gt; <div id="LastMDatecns!44A16F22F40F3BC1!205" style="FONT-SIZE: 10pt"&gt;2007年2月</div> <h4 id="subjcns!44A16F22F40F3BC1!205"&gt;sql server事务全攻略</h4> <div id="msgcns!44A16F22F40F3BC1!205" style="FONT-SIZE: 10pt"&gt; <div style="FONT-SIZE: 10pt"&gt;一 事务的属性 <p style="FONT-SIZE: 10pt"&gt;事务具有ACID属性 即 Atomic原子性,Consistent一致性,Isolated隔离性,Durable永久性 </p>

    <p style="FONT-SIZE: 10pt">原子性

    0 begin waitfor delay '00:00:10' print '不重复读' select * from table1 end

    0 ? ? ? ? ? ? ? begin ? ? ? ? ? ? ? ? print ? 'insert ? error' ? ? ? ? ? ? ? ? rollback ? ? ? ? ? ? ? end ? ? ? ? ? set ? @i=@i+1 ? ? ? commit ? ? end ? ? go ? ? ? ? ? ? ? 如果两个session同时执行这段话,肯定会在update何insert出现大量的错,这是因为这两个事务开始的时候,都是以select开始的,所以加的都是共享锁,所以导致两个事务读出来的有可能是同一个数,从而在在update何insert时会发生违反主键约束的错误。 ? ? ? ? 但是,只需把select和update换一下位置,就可以保证不发生上述情况,见下 ? ? create ? table ? table1 ? (s_id ? int ? primary ? key) ? ? create ? table ? table2 ? (n_id ? int ? primary ? key) ? ? insert ? into ? table1 ? values ? (1) ? ? go ? ? declare ? @i ? int ? ? declare ? @n_id ? int ? ? set ? @i=0 ? ? while ? (@i<5000) ? ? begin ? ? ? begin ? tran ? ? ? ? ? ? ? update ? table1 ? set ? s_id=s_id+1 ? ? ? ? ? if ? @@error<>0 ? ? ? ? ? ? begin ? ? ? ? ? ? ? ? print ? 'update ? error' ? ? ? ? ? ? ? ? rollback ? ? ? ? ? ? end ? ? ? ? ? select ? @n_id=s_id ? from ? table1 ? ? ? ? ? ? insert ? into ? table2 ? values ? (@n_id) ? ? ? ? ? if ? @@error<>0 ? ? ? ? ? ? ? begin ? ? ? ? ? ? ? ? print ? 'insert ? error' ? ? ? ? ? ? ? ? rollback ? ? ? ? ? ? ? end ? ? ? ? ? set ? @i=@i+1 ? ? ? commit ? ? end ? ? go ? ? ? ? ? 互换了一下位置,就不会出现select取重号的问题,这是事务先进行的是update语句,而update会加一个排他锁,这是很关键,因为它不会像select的共享锁一样,用完会释放,排他锁会一直维持到事务的结束(当然这种排他锁是在同一资源上的排他锁,而不是转化成了完全的事务锁,否则就蜕化成了serializable了),所以实际上,在update之后的select还是有排他锁保护的,所以不会出现重号的问题。 ? ? ? 可见在sql中锁的概念并不只限于资源锁,而是可以延伸到事务层面的事务锁。 ? ? ? ? ? 当然我不知道,这是sql在事务serializable和资源锁之间的一种故意的灵活性,还是出于一些别的目的,或者在别的方面还有更更加明显的体现或作用。 ? ? 可以肯定的就是利用这种锁的机制,改变update何select的顺序,起到的效果比serializable要好得多,因为没有在一些没必要顺序化的语句间保持顺序,而是在需要保证资源一致性的地方用了顺序处理,而在涉及不同资源的时候发挥了并发的特点,可以说是最有效的一种解决方案。??

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    <table id="layoutManager" cellspacing="0" cellpadding="0">

      推荐文章
        热点阅读