我主要是一名软件开发人员,但与大多数软件开发人员一样,我不得不不时地使用SQL。我的理解是,当您运行存储过程时,在该过程中创建的任何变量和临时表都属于运行,其中与其他操作隔离,并在执行结束时被处置。
在我目前的应用程序中,有一个Windows服务,一次从队列中获取几个“作业”,并为每个作业执行存储过程。它为每个作业创建一个新线程并同时运行它们。这是运行作业的代码:
var job = (Job)e.Argument;
rRepository rThread = new rRepository();
try
{
rThread.spJob(job.JobID);
}
catch (Exception ex)
{
logging.LogError(ex, "Error Running SP", job.JobID, true);
}
需要注意的重要一点是每次都要实例化一个新的rRepository。它是实体框架,因此应该为每个实现新的上下文/连接。
这已经好了多年,并没有给我们任何问题。但今天我在测试期间立刻解雇了很多这些,并得到了这个:
当前事务无法提交,也无法支持写入日志文件的操作。退回交易。
数据库中已经有一个名为“#Exclusions”的对象。
所以#Exclusions是在存储过程中使用的临时表。看起来这些同时运行的程序都可以访问彼此的临时表。
我找到了这个答案,这表明临时表不是线程安全的:Are temporary tables thread-safe? - 但仅当多个用户使用相同的连接时。在我的情况下,我有相同的连接字符串,但多个上下文。为什么我有线程问题?
答案 0 :(得分:2)
您可以创建仅对创建它们的存储过程可用的表变量:
DECLARE @t TABLE