когда я использую ServiceStack.OrmLite.SqlServer Db.Select <TableA>, иногда Result - это строки TableB или другие строки TableA - PullRequest
0 голосов
/ 27 апреля 2020
var user =  Db.Single<User>(x => x.Id==1); 
   if(user.Id!=1||user.Id==0)
{logger.Error($"Incorrect result{user.Id}")}

может видеть любой результат в файле журнала. Эта проблема беспокоила меня долгое время и никогда не видела прежде

Ответы [ 3 ]

1 голос
/ 27 апреля 2020

Я также думаю, что возможна проблема параллелизма. поэтому я кодирую простой выбор использования ADO. net, проблема по-прежнему

  string sql = $" select * from where Id=1 ";
                                using (SqlConnection connection = new SqlConnection(dbConnectionString))
                                {
                                    DataTable dt = new DataTable();
                                    connection.Open();
                                    SqlDataAdapter sda = new SqlDataAdapter(sql , connection);
                                    sda.Fill(dt);
                                    connection.Close();
                                    sda.Dispose();
                                    if (dt != null && dt.Rows.Count > 0)
                                    {
                                    var    user= dt.ToSingleModel<User>();
                                    }
                                } 
0 голосов
/ 30 апреля 2020

Сегодня произошла еще одна интересная вещь. В redis

key                    value
Urn:sid               {"__type":"UserSession"}               
OrderPaySettle        {"__type":"ServiceInterface.SettleOrder"}

Thread A Redis.Get<UserSession>("Urn:sid")    at 2020-04-29 06:27:53.0000
Thread B Redis.Get<object>("OrderPaySettle")  at 2020-04-29 06:27:53.8009
var item = Redis.Get<object>("OrderPaySettle") 

затем мы обнаружили, что тип элемента - UserSession в файле журнала

Несколько дней спустя go при анализе журнала база данных была почти то же самое. Был запрошен неверный результат, обычно тот, который был запрошен другим потоком и получил

Это похоже на проблему с памятью или сетевым уровнем? Каково ваше мнение по этому поводу? @ Mythz

0 голосов
/ 27 апреля 2020

Эту проблему сложно воспроизвести, и она появится только после миллионов запросов. Конечно, это может быть не так много, здесь не так много регулярности. Поэтому я только что загрузил код, и вы, возможно, не сможете его воспроизвести.

Чтобы перехватить журнал, я переписал SingleById

 public T SingleById( int id)
        {
            var result = Db.SingleById<T>(id);
            if (result == null || result.Id != id)
            {
                var first = result.ToIndentedJson();
                result = Db.SingleById<T>(id);
                if (result == null || result.Id != id)
                {
                    result =Db.SingleById<T>(id);
                    if (result != null)
                    {
                        LogQueryError(first,result, 2);
                    }
                }
                else
                {
                    LogQueryError(first, result, 1);
                }
            }          
            return result;    
        }

 public static readonly Logger LoggerMustDeal = LogManager.GetLogger("MustDeal");
 public void LogQueryError(string first, IEntityBase entityBase, int level = 1)
        {
            StackTrace st = new StackTrace(true);
            var frames = st.GetFrames();
            foreach (var sf in frames)
            {
                if (System.Diagnostics.StackFrame.OFFSET_UNKNOWN == sf.GetILOffset()) break;
                var fileName = sf.GetFileName();
                if (sf.GetMethod() == null || (!fileName.IsNullOrEmpty() && !fileName.Contains("LastOne")))
                {
                    break;
                }
                var str =
                    $"{fileName} {sf.GetMethod().Name} {sf.GetFileLineNumber()} {sf.GetFileColumnNumber()}";
                LoggerMustDeal.Error($"sqlserver error {str}");
            }


            LoggerMustDeal.Error($"sqlserver error first data {first}");
            LoggerMustDeal.Error($"sqlserver error times {level}  {entityBase.ToIndentedJson()} {Db.ConnectionString}");
            var spId = Db.Single<int>("select @@SPID");
            LoggerMustDeal.Error($"spid:{spId}");
        }

, теперь идентификатор журнала = 219 - это правильный результат, это только что произошло в производственной среде. И как ни странно, @@ SPID возвращает 0 или выдает исключение. Входная строка не была в правильном формате. Также как select @@ spid int, но вернуть varchar

2020-04-27 16:28:34.9112 ERROR sqlserver error first data {
  "Name": "",
  "StartTime": "0001-01-01T00:00:00",
  "EndTime": "0001-01-01T00:00:00",
  "ActivityType": 0,
  "ActivityRangeType": 0,
  "IsOpen": false,
  "ActivityFlag": null,
  "Timer": 0,
  "State": 2,
  "Id": 3,
  "Delstatus": false,
  "AddTime": "2020-02-04T18:36:03.883",
  "UpdateTime": "2020-04-27T10:04:13.713",
  "MallId": 1
}
2020-04-27 16:28:34.9112 ERROR sqlserver error times 1 {
  "Name": "test",
  "StartTime": "2020-04-18T00:00:00",
  "EndTime": "2020-04-19T00:00:00",
  "ActivityType": 1,
  "ActivityRangeType": 1,
  "IsOpen": true,
  "ActivityFlag": "test",
  "Timer": 0,
  "State": 2,
  "Id": 219,
  "Delstatus": false,
  "AddTime": "2020-04-13T17:38:48.83",
  "UpdateTime": "2020-04-13T17:38:48.83",
  "MallId": 15
} server=xxxx;uid=xxxx;pwd=xxxx;database=xxxx;max pool size=40000;Pooling=true;
...