Ste*_*ser 91 sql database transactions
我有一个读取查询,我在一个事务中执行,以便我可以指定隔离级别.查询完成后,我该怎么办?
做每一个有什么含义?
using (IDbConnection connection = ConnectionFactory.CreateConnection())
{
using (IDbTransaction transaction = connection.BeginTransaction(IsolationLevel.ReadUncommitted))
{
using (IDbCommand command = connection.CreateCommand())
{
command.Transaction = transaction;
command.CommandText = "SELECT * FROM SomeTable";
using (IDataReader reader = command.ExecuteReader())
{
// Read the results
}
}
// To commit, or not to commit?
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:问题不在于是否应该使用交易或是否有其他方法来设置交易级别.问题是,是否提交或回滚了不修改任何内容的事务.有性能差异吗?它会影响其他连接吗?还有其他差异吗?
Mar*_*ett 50
你提交.期.没有其他合理的选择.如果您开始了交易,则应该关闭它.提交释放您可能拥有的任何锁,并且对ReadUncommitted或Serializable隔离级别同样敏感.依赖隐式回滚 - 虽然技术上可能等同 - 只是糟糕的形式.
如果这还没有说服你,那么想象下一个在代码中间插入更新语句的人,并且必须追踪发生的隐式回滚并删除他的数据.
Gra*_*row 25
如果您没有更改任何内容,则可以使用COMMIT或ROLLBACK.任何一个都会释放你已经获得的任何读锁定,并且由于你没有做任何其他更改,它们将是等效的.
考虑嵌套事务。
大多数 RDBMS 不支持嵌套事务,或者尝试以非常有限的方式模拟它们。
例如,在 MS SQL Server 中,内部事务(这不是真正的事务,MS SQL Server 只是计算事务级别!)中的回滚将回滚最外层事务(这是真正的事务)中发生的所有事情。
某些数据库包装器可能会将内部事务中的回滚视为发生错误的标志,并回滚最外层事务中的所有内容,无论最外层事务是提交还是回滚。
因此,当您无法排除您的组件被某些软件模块使用时,COMMIT 是安全的方法。
请注意,这是对该问题的一般性回答。该代码示例通过打开新的数据库连接巧妙地解决了外部事务的问题。
关于性能:根据隔离级别,SELECT 可能需要不同程度的 LOCK 和临时数据(快照)。当交易关闭时,这将被清除。这是通过 COMMIT 还是 ROLLBACK 完成的并不重要。所花费的 CPU 时间可能存在微不足道的差异 - COMMIT 的解析速度可能比 ROLLBACK 更快(少两个字符)以及其他细微差异。显然,这只适用于只读操作!
完全没有要求:另一个可能阅读代码的程序员可能会认为回滚意味着错误情况。