我有一个AWS lambda函数,该函数会响应SNS消息而执行。有一些莫名其妙的行为发生,子方法突然停止执行(好像引发了异常),但是父方法随后继续照常执行。
public void InsertEntity(Entity entity)
{
_context.Entities.Add(entity);
_logger.Log($"Before SaveChanges, entity.Id is {entity.Id}");
_context.SaveChanges();
_logger.Log($"After SaveChanges, entity.Id is {entity.Id}");
if (entity.Id < 0)
throw new Exception($"InsertEntity succeeded, but id is invalid: {entity.Id}");
}
public int? ImportEntity(string xml)
{
var entity = new Entity(xml);
_entityRepository.InsertEntity(entity);
_logger.LogLine($"Entity inserted successfully with Id {entity.Id}");
return entity.Id;
}
在这种情况下,上下文是使用PostgreSQL EF提供程序的标准DbContext。
首次创建实体时,Id为0。将其添加到上下文DbSet中时,id变为一个临时负整数,如-2147392341
。调用SaveChanges后,应从数据库中为实体提供一个ID,一个正数。
这里的任何异常都应该冒泡到调用ImportEntity的方法上,并且应该处理错误。相反,我在AWS中的日志文件如下所示:
Before SaveChanges, entity.Id is -2147482647
Entity inserted successfully with Id -2147482647
并且在任何时候都不会引发异常的情况下返回负值。由于我在InsertEntity中有专门检查负值的代码,因此我唯一看到的可能性是SaveChanges引发了一个异常,该异常导致日志记录和否定检查都无法运行。但是父方法如何继续记录和执行并返回值?
我知道我的代码正在AWS上更新,因为我最近添加了“ SaveChanges”日志并显示了日志,并且同时添加了所有日志。
编辑:
我直接在_context.SaveChanges();
周围添加了try / catch并能够捕获潜在的异常。问题仍然存在,即使从ImportEntity
内部抛出异常,为什么/如何继续执行InsertEntity
函数。
编辑2 :
添加csproj定义:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<AssemblyName>MyService</AssemblyName>
<OutputType>Library</OutputType>
<PackageId>MyService</PackageId>
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
</PropertyGroup>
<ItemGroup>
<None Update="runtimes\linux\lib\netstandard1.3\System.Net.NetworkInformation.dll">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Amazon.Lambda.Core" Version="1.0.0" />
<PackageReference Include="AWSSDK.S3" Version="3.3.16.2" />
<PackageReference Include="Amazon.Lambda.Serialization.Json" Version="1.1.0" />
<PackageReference Include="Amazon.Lambda.S3Events" Version="1.0.2" />
<PackageReference Include="AWSSDK.XRay" Version="3.3.1.6" />
<PackageReference Include="AWSXRayRecorder" Version="2.0.0-beta" />
<PackageReference Include="AWSXRayRecorder.Handlers.AwsSdk" Version="2.0.0-beta" />
<PackageReference Include="Castle.Core" Version="4.2.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.0.1" />
<PackageReference Include="HtmlAgilityPack.NetCore" Version="1.5.0.1" />
<PackageReference Include="Amazon.Lambda.SNSEvents" Version="1.0.0" />
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.1" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.0" />
<PackageReference Include="AWSSDK.SimpleNotificationService" Version="3.3.0.24" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Amazon.Lambda.Tools" Version="2.1.0" />
</ItemGroup>
</Project>
以及AWS调用的顶级lambda方法,然后调用ImportEntity:
public void ProcessEntity(SNSEvent evnt, ILambdaContext context)
{
var fileContent = GetFileContent(evnt);
using (var lifetimeScope = Container.BeginLifetimeScope())
{
var processor = processingScope.Resolve<IEntityProcessor>();
var result = processor.ImportEntity(fileContent);
context.Logger.LogLine($"Successfully imported entity, Id is {result.Value}");
return result;
}
}
答案 0 :(得分:4)
这个问题已经出现过很多次了。我怀疑根本原因与未等待的异步进程引发异常时发生的情况类似:它们不会冒泡到您的代码,因为它们并非旨在这样做。
在其他情况下,此类问题已解决,则根故障通常在代码外部,这意味着数据库连接,映射中的某个位置,甚至在数据库端本身。当发生这种情况时,线程将简单地死掉,并且执行将继续,就像SaveChanges已正常返回一样。
数据库超时可能会导致此行为。类似于POCO文件的文件与数据库不正确一样,也可能导致该文件,并且您可能不会收到警告。 32位和64位文件位置之间的混乱可能会导致这种情况。如果数据库是事务性的,脏的ObjectStateEntry对象无法持久保存,则任何事务失败都会导致这种情况。
我将从查看数据库中的错误日志开始-令人惊讶的是,这样做时问题频繁出现。如果日志未显示问题,则将工具放在数据库端,然后查看接收到的查询,查询结果和查询执行。那很可能会指出正确的方向。
如果这不能使您畅通无阻,则值得花时间进行完整且可执行的最小化复制并发布。这将为我提供寻找问题根源所需的一切。