在ADO.NET中使用事务保护数据的完整性(2)
2024-07-10 13:03:11
供稿:网友
事务剖析
事务最基本上包含两个步骤 – 开始, 然后是提交或回滚. 开始调用定义了事务的边界, 同时调用提交或回滚在定义结束. 在事务边界内, 所有的执行描述被认为是完成任务的一部分, 必须作为成功或失败的一种. 如果一切都成功提交将会执行所有的数据修改, 如果有任何错误发生, 回滚将会取消修改. 所有的.net 数据提供对象提供了类似的类和方法来完成这些操作.
孤立等级
孤立等级在事务中界定事务孤立行为. 越是孤立等级越高, 数据越不会被别的事务干扰. 许多数据库通过加锁来增强孤立等级. 你应该实行两次检查你目标dbms使用.好的做法是在性能和并发上折衷, 较多的锁系统将不得不维护, 越多的话容易造成冲突并且会降低速度对于不同的处理来说.
以下列表是孤立等级对于ado.net的支持, 来自于.net framewok sdk. 以下列表孤立等级限制性越来越强.
member name
description
value
unspecified
supported by the .net compact framework.
a different isolation level than the one specified is being used, but the level cannot be determined.
-1
chaos
supported by the .net compact framework.
the pending changes from more highly isolated transactions cannot be overwritten.
16
readuncommitted
supported by the .net compact framework.
a dirty read is possible, meaning that no shared locks are issued and no exclusive locks are honored.
256
readcommitted
supported by the .net compact framework.
shared locks are held while the data is being read to avoid dirty reads, but the data can be changed before the end of the transaction, resulting in non-repeatable reads or phantom data.
4096
repeatableread
supported by the .net compact framework.
locks are placed on all data that is used in a query, preventing other users from updating the data. prevents non-repeatable reads but phantom rows are still possible.
65536
serializable
supported by the .net compact framework.
a range lock is placed on the data set, preventing other users from updating or inserting rows into the dataset until the transaction is complete.
1048576
小注: 无序的孤立等级是不被sql server 或 oracle 支持的, 只有oledb 数据提供对象将会作为孤立等级设置事务接受它. 如果试图用sql server 或oracle 设置它,将会得到一个argumentexception, 指明无效的孤立等级参数.
sql server 和 oracle 和 ole db 数据提供对象默认为readcommitted 孤立等级. odbc 数据提供对象默认孤立等级各不相同, 依赖于odbc的驱动的不同. 如果你考虑readcommitted 不是你想要的孤立等级, 你可以使用transaction.isolationlevel 属性来 指定不同的等级. 你应该非常慎重考虑修改这些设置,虽然, 执行适当的测试来保证,这些变化不能影响数据的一致性,或其它的并发问题. 如果有数据库管理员, 你应该向他们请教关于特定任务的恰当等级.你也应该查看数据库文档来看你的数据库是如何处理孤立等级和锁的.
局部回滚
通常情况下,如果一个事务发生错误,你会发现你想回滚的地方并不是整个事务.只有当你完全成功处理完某个事务需要大量的时间时,你希望会这样做. 但检查部分执行成功将会开销很大. 你要平衡数据修改成本和不得不回滚一些小的的部分来避免开支过大.
部分回滚通常使用savepoints或者是内嵌事务, 主要依赖于你的数据库是如何工作的. 一些dbms 或者不提供这种机制,因此查看你的数据库文档看是否或如何实现局部回滚.
sql server 和 oracle 允许使用 savepoints (当造成回滚时你可以引用)来停止回滚在预定的点.他们不真正的执行内嵌的事务,另外的一些dbmss来完成同样的工作. sql server 在最简单的意义上允许使用内嵌的事务, 你可以使用内嵌的开始...提交t-sql块语句.然而, 只有在提交以外事实上提交了所有的事务,在提交过程以内仅仅是消耗系统变量,因此你可以跟踪多少事务你有多少已经打开的事务.
一些数据库执行了真正的内嵌事务. 对这些数据类型来说,内嵌的提交将会实际上提交响应的事务,即使外部的事务回滚内嵌事务仍然会提交.