判断SqlTransaction是写数据还是只读

本文关键字:只读 数据 SqlTransaction 判断 | 更新日期: 2023-09-27 17:50:53

我首先要说的是,我很确定这是不可能的。在谷歌上没有人问这个问题,所以我抱着悲观的希望。

我正在使用SqlTransaction连接到数据库,并允许几个消费者在我关闭它之前使用这个事务。是否有可能确定事务是仅用于读取数据还是读取/写入数据,即使可能已经使用了存储过程?是否存在一些属性或SQL方法(除了执行一些邪恶的diff)可以检查这个?

判断SqlTransaction是写数据还是只读

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

SELECT writes FROM sys.dm_exec_sessions WHERE session_id = @@SPID
但是,

会带来一些开销。我认为车管所是O(N)在会话运行的数量。会话越多,系统速度越慢。最终,它变成了一个负缩放的例子。

注意,这是每个会话的值。如果每个会话有多个事务(每次打开SqlConnection对象),写操作将被累积跟踪。你需要考虑到这一点,或者在另一个答案中使用这个想法。

您可以使用sys。查看事务状态

当一个事务被打开,但是没有工作(select only),它不注册,但是如果你做了任何工作,事务日志的大小就会增加。

先试试这个…注意你的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_观点……

在事务中有记录之前,视图是空白的。选择不被记录

别忘了回滚。

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

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

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

正如我所说的,这只是一个想法。,)我希望这对你有所帮助,或者至少给你一些关于如何做的想法