关于SQL Server事务处理的一系列问题。我分有多,只要能给出详细答案,我愿按字算分。(1)

Ivony 2006-06-16 11:02:03
1、SQL Server的COMMIT TRANSACTION是不是提交所有的事务,如果事务嵌套的话,是不是应该为每一个事务指定名称而避免内层事务COMMIT提交所有事务处错。如果是这样,那么ADO.NET的BeginTransaction方法创建的事务是否具备一个唯一名称,外层ADO.NET开启一个事务调用存储过程,而存储过程内又开启一个事务会不会出问题,我测试似乎并不稳定,期待高人解答。

2、SQL Server的事务在出错的时候是不是会自动回滚?多么严重的错误会导致回滚?是不是有任何设置能让它不回滚,也就是这一点是可以完全信赖的吗?

3、我知道UPDATE/DELETE语句如果没有更新任何记录不算错误,那么如果是要求他们一定要对数据库进行操作,是否应该在这些语句前写SELECT判断是否有满足筛选条件的任何记录?还是应该在操作后判断@@ROWCOUNT?那么在之前用SELECT判断的话,事务能不能保证在执行SELECT语句到执行UPDATE/DELETE这段时间之内数据库相关的行列不会有任何改动导致SELECT的结果有可能变化?在执行完UPDATE/DELETE到判断@@ROWCOUNT之间会不会有任何因素(除了在当前事务中再执行一段UPDATE/INSERT语句)改变@@ROWCOUNT?

4、如果INSERT失败是否一定会导致事务回滚?如果不是,哪些情况会导致?

5、如果INSERT/UPDATE/DELETE操作遇到约束导致失败,会不会回滚事务?

6、如果INSERT/UPDATE/DELETE操作的触发器所进行的操作发生错误,会不会回滚事务?

7、如果操作遇到权限问题导致失败,会不会回滚事务?


最后问一个附加问题。
SQL Server要用到跨库跨服务器的事务的时候,应该用分布式事务吗?用什么分布式事务比较好?
...全文
1152 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
being21 2006-07-14
  • 打赏
  • 举报
回复
我看还是先MARK,再看!!!
ldw701 2006-07-14
  • 打赏
  • 举报
回复
mark
addwing 2006-06-19
  • 打赏
  • 举报
回复
留念,学习,帮你顶!
昵称被占用了 2006-06-17
  • 打赏
  • 举报
回复
理解
csdn的特点决定事务问题在这里很难说明白,一边做一般问吧,具体问题好解决些
事务比较大的话最好硬件配置高些,要不急死自己,呵呵



Ivony 2006-06-17
  • 打赏
  • 举报
回复
总体来说,我觉得你不必关心自动回滚,你保证自己的存储过程代码都是在显式事务的控制下,就能达到你的要求,不管是权限问题还是运行时错误或编译错误。只有意外情况(比如网络中断)交给自动回滚



这个,因为我在写牵涉到资金/商品的东西,对事务这一块非常敏感,因为可能一个操作引发的连锁反应非常大,可能有二三十条SQL语句牵涉其中,而这些SQL语句并不是能够在一开始就算好的,而是程序根据实际情况产生的。所有的SQL语句要么全部成功要么全部失败,如果执行到一半退出那就完蛋了……
Ivony 2006-06-17
  • 打赏
  • 举报
回复
嗯……第一个问题基本明白了,我回头再去试试。
昵称被占用了 2006-06-17
  • 打赏
  • 举报
回复
呵呵,挺富有嘛,不过也就中国队水平,进不了世界杯,这个说着玩的,别当真

总体来说,我觉得你不必关心自动回滚,你保证自己的存储过程代码都是在显式事务的控制下,就能达到你的要求,不管是权限问题还是运行时错误或编译错误。只有意外情况(比如网络中断)交给自动回滚





昵称被占用了 2006-06-17
  • 打赏
  • 举报
回复
从你的问题看你没理解帮助的文字,举个例子:

你的问题:
如果是这样,那么ADO.NET的BeginTransaction方法创建的事务是否具备一个唯一名称,外层ADO.NET开启一个事务调用存储过程,而存储过程内又开启一个事务会不会出问题,我测试似乎并不稳定,期待高人解答。

帮助文字:
每个事务都必须只由其中的一种方法管理。在同一事务中使用两种方法可能导致不确定的结果。例如,不应先使用 ODBC API 函数启动一个事务,再使用 Transact-SQL COMMIT 语句完成该事务。这样将无法通知 SQL Server ODBC 驱动程序该事务已被提交。在这种情况下,应使用 ODBC SQLEndTran 函数结束该事务。


自己比较下


Ivony 2006-06-17
  • 打赏
  • 举报
回复
Ivony 您好

目前你在CSDN社区有可用分:4608, 总信誉分是:100, 总专家分是:15587,


分数不用担心吧……:)
Ivony 2006-06-17
  • 打赏
  • 举报
回复
算字数按手敲的算,你copy的那些我都看过了 : )……
Ivony 2006-06-17
  • 打赏
  • 举报
回复
拷贝点帮助文字多挣点分,呵呵,还算厚道,没复制示例部分:

下略。

这一点帮助我已经看过了,可是他还是没有给我一个准确的答案。例如运行时错误和编译错误以及批处理怎么判断我都不知道。

其实我就是想知道,我该怎么写才能保证一系列操作的原子性,绝对不会中途中断而不回滚。


例如,如果我在存储过程中调用另一个存储过程,而另一个存储过程所用到的表忽然消失了,或者其他原因导致另外一个存储过程根本就没法启动。那么这是不是算编译错误或者运行时错误?如果这样出错,会不会回滚事务?如果我强调一定要回滚我该怎么做?
昵称被占用了 2006-06-17
  • 打赏
  • 举报
回复
--7、如果操作遇到权限问题导致失败,会不会回滚事务?

也要参考第2题,select 权限问题和其他的权限问题一样的
昵称被占用了 2006-06-17
  • 打赏
  • 举报
回复
晕,我最喜欢抄联机丛书(其实更懒,是copy)

lz看看我抄的对你有没用?没用我不抄了
昵称被占用了 2006-06-17
  • 打赏
  • 举报
回复
个人理解

--1、SQL Server的COMMIT TRANSACTION是不是提交所有的事务,如果事务嵌套的话,是不是应该
--为每一个事务指定名称而避免内层事务COMMIT提交所有事务处错。如果是这样,那么ADO.NET的
--BeginTransaction方法创建的事务是否具备一个唯一名称,外层ADO.NET开启一个事务调用存储
--过程,而存储过程内又开启一个事务会不会出问题,我测试似乎并不稳定,期待高人解答。

--SQL Server的COMMIT TRANSACTION是不是提交所有的事务
这个肯定不是了,COMMIT TRANSACTION语法如下,是可以指定事务的
COMMIT [ TRAN [ SACTION ] [ transaction_name | @tran_name_variable ] ]

--如果事务嵌套的话,是不是应该为每一个事务指定名称而避免内层事务COMMIT提交所有事务处
--错。
这是必需的

--如果是这样,那么ADO.NET的BeginTransaction方法创建的事务是否具备一个唯一名称,外层
--ADO.NET开启一个事务调用存储过程,而存储过程内又开启一个事务会不会出问题,我测试似乎
--并不稳定,期待高人解答。
--ADO、ADO.NET的事务和数据库的事务是不同的概念,所以没有“如果是这样”
需要看相关代码才能发现问题在哪里

--2、SQL Server的事务在出错的时候是不是会自动回滚?多么严重的错误会导致回滚?是不是有
--任何设置能让它不回滚,也就是这一点是可以完全信赖的吗?

拷贝点帮助文字多挣点分,呵呵,还算厚道,没复制示例部分:

(1)、SET XACT_ABORT
指定当 Transact-SQL 语句产生运行时错误时,Microsoft® SQL Server™ 是否自动回滚当前事务。

语法
SET XACT_ABORT { ON | OFF }

注释
当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句产生运行时错误,整个事务将终止并回滚。为 OFF 时,只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。编译错误(如语法错误)不受 SET XACT_ABORT 的影响。

对于大多数 OLE DB 提供程序(包括 SQL Server),隐性或显式事务中的数据修改语句必须将 XACT_ABORT 设置为 ON。唯一不需要该选项的情况是提供程序支持嵌套事务时。有关更多信息,请参见分布式查询和分布式事务。

SET XACT_ABORT 的设置是在执行或运行时设置,而不是在分析时设置。

(2)、事务处理过程中的错误
如果服务器错误使事务无法成功完成,SQL Server 将自动回滚该事务,并释放该事务占用的所有资源。如果客户端与 SQL Server 的网络连接中断了,那么当网络告知 SQL Server 该中断时,将回滚该连接的所有未完成事务。如果客户端应用程序失败或客户计算机崩溃或重启,也会中断该连接,而且当网络告知 SQL Server 该中断时,也会回滚所有未完成的连接。如果客户从该应用程序注销,所有未完成的事务也会被回滚。

如果批处理中出现运行时语句错误(如违反约束),那么 SQL Server 中默认的行为将是只回滚产生该错误的语句。可以使用 SET XACT_ABORT 语句改变该行为。在 SET XACT_ABORT ON 语句执行之后,任何运行时语句错误都将导致当前事务自动回滚。编译错误(如语法错误)不受 SET XACT_ABORT 的影响。

如果出现运行时错误或编译错误,那么程序员应该编写应用程序代码以便指定正确的操作(COMMIT 或 ROLLBACK)。

(3)、隐性事务(少用,可以不理它)
SET IMPLICIT_TRANSACTIONS
为连接设置隐性事务模式。

语法
SET IMPLICIT_TRANSACTIONS { ON | OFF }

注释
当设置为 ON 时,SET IMPLICIT_TRANSACTIONS 将连接设置为隐性事务模式。当设置为 OFF 时,则使连接返回到自动提交事务模式。

当连接是隐性事务模式且当前不在事务中时,执行下列语句将启动事务:

ALTER TABLE FETCH REVOKE
CREATE GRANT SELECT
DELETE INSERT TRUNCATE TABLE
DROP OPEN UPDATE


如果连接已经在打开的事务中,则上述语句不启动新事务。

对于因为该设置为 ON 而自动打开的事务,用户必须在该事务结束时将其显式提交或回滚。否则当用户断开连接时,事务及其所包含的所有数据更改将回滚。在事务提交后,执行上述任一语句即可启动新事务。

隐性事务模式将保持有效,直到连接执行 SET IMPLICIT_TRANSACTIONS OFF 语句使连接返回到自动提交模式。在自动提交模式下,如果各个语句成功完成则提交。

在进行连接时,SQL Server ODBC 驱动程序和用于 SQL Server 的 Microsoft OLE DB 提供程序自动将 IMPLICIT_TRANSACTIONS 设置为 OFF。对来自 DB-Library 应用程序的连接,SET IMPLICIT_TRANSACTIONS 默认为 OFF。

当 SET ANSI_DEFAULTS 为 ON 时,将启用 SET IMPLICIT_TRANSACTIONS。

SET IMPLICIT_TRANSACTIONS 的设置是在执行或运行时设置,而不是在分析时设置。


--3、我知道UPDATE/DELETE语句如果没有更新任何记录不算错误,那么如果是要求他们一定要对
--数据库进行操作,是否应该在这些语句前写SELECT判断是否有满足筛选条件的任何记录?还是
--应该在操作后判断@@ROWCOUNT?那么在之前用SELECT判断的话,事务能不能保证在执行SELECT
--语句到执行UPDATE/DELETE这段时间之内数据库相关的行列不会有任何改动导致SELECT的结果有
--可能变化?在执行完UPDATE/DELETE到判断@@ROWCOUNT之间会不会有任何因素(除了在当前事务
--中再执行一段UPDATE/INSERT语句)改变@@ROWCOUNT?
发现lz很少看帮助,正常来说,用exists判断是最好的,用select也可以判断,用@@ROWCOUNT事后判断大部分情况也是没问题的,除非1、你自己程序失误,没在执行语句后马上判断。2、你修改的表有触发器,这点很重要,有触发器的表用@@ROWCOUNT判断会给自己找很多麻烦。

--4、如果INSERT失败是否一定会导致事务回滚?如果不是,哪些情况会导致?
--5、如果INSERT/UPDATE/DELETE操作遇到约束导致失败,会不会回滚事务?
看第2题吧,提醒下:不要把INSERT/UPDATE/DELETE操作分开,对事务来说,它们一样的。

--6、如果INSERT/UPDATE/DELETE操作的触发器所进行的操作发生错误,会不会回滚事务?
触发器代码的执行过程,相当于在触发触发器的语句执行的时候有个显式的事务开始,在触发器完成后有个显式的事务提交。所以,会回滚事务。


Ivony 2006-06-16
  • 打赏
  • 举报
回复
1、SQL Server的COMMIT TRANSACTION是不是提交所有的事务,如果事务嵌套的话,是不是应该为每一个事务指定名称而避免内层事务COMMIT提交所有事务处错。如果是这样,那么ADO.NET的BeginTransaction方法创建的事务是否具备一个唯一名称,外层ADO.NET开启一个事务调用存储过程,而存储过程内又开启一个事务会不会出问题,我测试似乎并不稳定,期待高人解答。
这个比较复杂 微软建议在必要的情景下做commit/rollback

这个没看明白,我想弄清楚的是要怎要做才不会报什么“事务个数与提交次数不符”(好像是这样的意思)这样的错误。


2、
出错的时候自动回滚,只不过设置了xact_abort为on的事务全部回滚,否则单句回滚。

是指如果事务设置了xact_abort,则整个事务全部回滚了,但如果没设置,则把这一条语句所做的操作全部回滚然后报错吗?那么这条语句没在事务里面如果出错的话,好像也会回滚哈,也就是说如果事务没有设置xact_abort,就不会回滚了对吗?那么,怎样确保事务设置了xact_abort呢?


第3个问题我说明一下。
比如说我要删除某条记录,同时进行一些其他的操作,如果这条记录根本就不存在,则其他的操作同样不想运行(如记录日志)。也就是说我必须确认确实是删除了一条记录才进行一些操作。这个时候我就有两种选择,一是删除之前SELECT一下看看这条记录是不是真的存在。二是删除后检查@@ROWCOUNT是否为期望的值,哪一种方式比较好。如果用第一种方式,那么事务能保证我执行SELECT和UPDATE两条语句之间不会有任何其他的因素导致SELECT的结果改变吗?(前提是事务内没有任何操作会导致这一点),如SELECT之后,别的人删掉了这条记录。如果采取第二种方案,事务能保证我的@@ROWCOUNT是有效的吗,不会受到其他因素的影响,如其他的因素影响了@@ROWCOUNT的值。

第7个问题可能我没说清楚,我想知道即使是SELECT遇到了权限问题,也会导致整个事务回滚吗?

在这里回答问题的人,不论是不是君子,麻烦也到各个分贴露个脸。我也在CSDN混的,深知专家分难混,尤其是在这种冷板块。更知道原创的答案多么难得,如果只是抄抄联机丛书,得,您告诉我在哪一页就行了,我这里有全的。所以,愿高分相赠原创的回答。

http://community.csdn.net/Expert/TopicView.asp?id=4825072
rouqu 2006-06-16
  • 打赏
  • 举报
回复
sorry msdtc
rouqu 2006-06-16
  • 打赏
  • 举报
回复
1、SQL Server的COMMIT TRANSACTION是不是提交所有的事务,如果事务嵌套的话,是不是应该为每一个事务指定名称而避免内层事务COMMIT提交所有事务处错。如果是这样,那么ADO.NET的BeginTransaction方法创建的事务是否具备一个唯一名称,外层ADO.NET开启一个事务调用存储过程,而存储过程内又开启一个事务会不会出问题,我测试似乎并不稳定,期待高人解答。
这个比较复杂 微软建议在必要的情景下做commit/rollback

2、SQL Server的事务在出错的时候是不是会自动回滚?多么严重的错误会导致回滚?是不是有任何设置能让它不回滚,也就是这一点是可以完全信赖的吗?

出错的时候自动回滚,只不过设置了xact_abort为on的事务全部回滚,否则单句回滚。语句不能够执行即回滚,逻辑出错但可以正常执行的语句不在此列。按照SQL Server的设计原则,日志优先写入,要不日志都还没有写,要不日志写了之后重绕日志或卷回日志,始终能保持数据的一致性。

3、我知道UPDATE/DELETE语句如果没有更新任何记录不算错误,那么如果是要求他们一定要对数据库进行操作,是否应该在这些语句前写SELECT判断是否有满足筛选条件的任何记录?还是应该在操作后判断@@ROWCOUNT?那么在之前用SELECT判断的话,事务能不能保证在执行SELECT语句到执行UPDATE/DELETE这段时间之内数据库相关的行列不会有任何改动导致SELECT的结果有可能变化?在执行完UPDATE/DELETE到判断@@ROWCOUNT之间会不会有任何因素(除了在当前事务中再执行一段UPDATE/INSERT语句)改变@@ROWCOUNT?
??看不太明白

4、如果INSERT失败是否一定会导致事务回滚?如果不是,哪些情况会导致?
一定 但你可以在回滚面上控制

5、如果INSERT/UPDATE/DELETE操作遇到约束导致失败,会不会回滚事务?
一定 但你可以在回滚面上控制

6、如果INSERT/UPDATE/DELETE操作的触发器所进行的操作发生错误,会不会回滚事务?
不管是触发器操作还是函数操作 只要相应的DML发生错误 系统一定回滚。

7、如果操作遇到权限问题导致失败,会不会回滚事务?
一定

最后问一个附加问题。
SQL Server要用到跨库跨服务器的事务的时候,应该用分布式事务吗?用什么分布式事务比较好?
当然 相关的机器都要开启mstsc服务,比如分布式分区视图、Failover群集。
Ivony 2006-06-16
  • 打赏
  • 举报
回复
继续等待补全答案。
Ivony 2006-06-16
  • 打赏
  • 举报
回复
即使嵌套事务内部的 COMMIT TRANSACTION transaction_name 语句引用外部事务的事务名,该提交也只应用于最内层的事务


那么COMMIT TRANSACTION transaction_name这种语法有什么用处呢?
splory 2006-06-16
  • 打赏
  • 举报
回复
如果在一组嵌套事务的任意级别执行使用外部事务名称的 ROLLBACK TRANSACTION transaction_name 语句,那么所有的嵌套事务都将回滚。
加载更多回复(7)

34,576

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧