Sql 我应该提交还是回滚读取事务?
我有一个在事务中执行的读取查询,以便指定隔离级别。查询完成后,我应该怎么做Sql 我应该提交还是回滚读取事务?,sql,database,transactions,Sql,Database,Transactions,我有一个在事务中执行的读取查询,以便指定隔离级别。查询完成后,我应该怎么做 提交事务 回滚事务 不执行任何操作(这将导致事务在使用块结束时回滚) 每种方法的含义是什么 using (IDbConnection connection = ConnectionFactory.CreateConnection()) { using (IDbTransaction transaction = connection.BeginTransaction(IsolationLevel.ReadUnc
- 提交事务
- 回滚事务
- 不执行任何操作(这将导致事务在使用块结束时回滚)
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?
}
}
编辑:问题不是是否应该使用事务,或者是否有其他方法来设置事务级别。问题是,提交或回滚一个不修改任何内容的事务是否有任何区别。是否存在性能差异?它会影响其他连接吗?还有其他区别吗?如果读取不会改变状态,我将什么也不做。执行提交除了浪费一个向数据库发送请求的周期外,什么都不会做。您尚未执行已更改状态的操作。回滚也是如此
但是,您应该确保清理对象并关闭与数据库的连接。如果重复调用此代码,不关闭连接可能会导致问题。是否需要阻止其他人读取相同的数据?为什么要使用事务 @Joel-我的问题最好用“为什么在读取查询中使用事务?” @Stefan-如果要使用AdhocSQL而不是存储过程,那么只需在查询中的表之后添加WITH(NOLOCK)。这样,您就不会在事务的应用程序和数据库中产生开销(尽管是最小的)
SELECT * FROM SomeTable WITH (NOLOCK)
EDIT@Comment 3:因为问题标签中有“sqlserver”,所以我假设MSSQLServer是目标产品。现在,这一点已经澄清,我已经编辑了标签,以删除特定的产品参考
我仍然不知道为什么您首先要在read op上进行事务处理 只是一个旁注,但您也可以这样编写代码:
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())
{
// Do something useful
}
// To commit, or not to commit?
}
如果您稍微重新构造一些东西,您可能也可以将IDataReader的using块移到顶部。如果您开始事务,那么最佳做法就是始终提交它。如果在使用(事务)块中抛出异常,事务将自动回滚。在您的代码示例中
注意:如果您正在执行多个read语句,并且希望它们都“看到”与第一个语句相同的数据库状态,则需要将隔离级别设置为top Repeatable read或Serializable…如果您没有更改任何内容,则可以使用COMMIT或ROLLBACK。任何一个都将释放您获得的任何读锁,并且由于您没有进行任何其他更改,因此它们将是等效的。如果您将SQL放入存储过程并将其添加到查询上方:
set transaction isolation level read uncommitted
那么你就不必在C代码中跳过任何障碍。在存储过程中设置事务隔离级别不会导致该设置应用于该连接的所有未来使用(这是由于连接是池化的,所以您必须担心的问题)。在存储过程结束时,它只返回到初始化连接时使用的任何连接。您可以提交。时期没有其他明智的选择。如果您启动了一个事务,您应该关闭它。提交将释放您可能拥有的所有锁,并且对于ReadUncommitted或Serializable隔离级别同样敏感。依赖隐式回滚(虽然在技术上可能是等效的)只是一种糟糕的形式
如果你没有说服你,想象下一个在你的代码中间插入一个更新语句的人,并且必须跟踪发生的隐式回滚并删除他的数据。
- 查询不会重新启动