确定SqlTransaction是写入数据还是只读

时间:2014-03-18 18:47:51

标签: c# sql-server ado.net

我首先要说的是我很确定这是不可能的。谷歌搜索没有提出任何问这个问题的人,所以我悲观地抱有希望。

我正在使用SqlTransaction连接到数据库,并允许多个使用者在关闭它之前使用此事务。是否可以确定事务是否仅用于读取数据或读取/写入数据,即使可能已使用存储过程?是否存在可以检查此属性的某些属性或SQL方法(除执行某些不合理的差异外)?

3 个答案:

答案 0 :(得分:3)

sys.dm_exec_sessions有一列writes。您可以这样查询:

SELECT writes FROM sys.dm_exec_sessions WHERE session_id = @@SPID
但是,这会带来一些开销。我认为DMV在运行的会话数中是O(N)。系统将减慢更多会话的速度。最终它变成了负面缩放的情况。

请注意,这是每会话值。如果每个会话有多个事务(每个SqlConnection对象打开),则将累积跟踪写入。您需要考虑到这一点,或者在其他答案中使用这个想法。

答案 1 :(得分:2)

您可以使用sys.dm_视图来检查事务状态。

当一个事务被打开但没有工作完成时(仅选择),它没有注册,但如果你做任何工作,事务日志的大小就会增加。

首先尝试这个...记下您的SPID。

USE tempdb
begin tran
create table dave (id int)
insert into dave (id) select 1
-- rollback tran

保持事务处于打开状态,然后用它来查看它(替换你的spid):

select database_transaction_log_bytes_used, *
from sys.dm_tran_database_transactions dt 
inner join sys.dm_tran_active_transactions at on (at.transaction_id = dt.transaction_id)   
inner join sys.dm_tran_session_transactions st on (st.transaction_id = dt.transaction_id) 
where (dt.database_id = DB_ID('tempdb')) and (st.is_user_transaction=1) 
and session_id=83

然后回滚原始文件。

然后试试这个:

USE tempdb
begin tran
select getdate()
-- rollback tran

在sys.dm_ views ...

上运行上面的内容

在事务中记录某些内容之前,视图为空白。选择不记录。

别忘了把它全部卷回来。

因此,您可以在关闭事务之前编写一个可以查询的proc / view,假设您知道spid(很容易查询SELECT @@SPID),它将返回活动会话的日志大小。

答案 2 :(得分:0)

mmm, This is only an idea 。我正在考虑像...在数据库中创建一个表,调用CountRead和另一个表CountWrite,然后,如果查询是SELECT,则修改您的查询以写入读表如果查询是INSERT或其他东西,写表。然后,当您想要检查是否只读或写时,您只需要读取这些表(如果它们已经有数据,您可以在应用程序启动时删除所有数据,或者在开始时检查计数)。

然后通过对这些表的简单SELECT,您将能够检查是否只使用了读取查询,或者只是写入查询,或者两者都是,以及多少次。

正如我所说,这只是一个想法。 ;)我希望这有帮助,或者至少让你知道如何做到这一点