一.应用场景
给第三方微信支付平台做接口时,接口访问数据库时间长,微信平台只等30秒,超过时交易失败.而我们的程序是不会超时的,因此造成双方交易状态不一致.
二.解决思路
(1)数据库肯定是存在问题的,因为客观原因暂时不能解决数据库的问题.
(2)只能从接口程序上解决问题.将原来的业务处理放入Task1并执行,主线程计时循环等待.当超过20秒时,创建Task2去等待Task1执行完后,回滚数据库事务,主线程返回失败给微信平台.如果Task1在20秒内执行完成时,跳出循环,提交数据库事务,并返回成功状态给微信平台.
三.测试代码
static string DoSql()
{
var connstr = ConfigurationManager.ConnectionStrings["OracleDbContext"].ToString();
OracleConnection conn = new OracleConnection(connstr);
conn.Open();
OracleTransaction tr = conn.BeginTransaction();
OracleCommand cmd1 = conn.CreateCommand();
bool tf = false;
Stopwatch sw = new Stopwatch();
sw.Start();
Console.WriteLine("-------------Main start ---------------------");
Task t1 = new Task(() => {
Console.WriteLine("-------------Task1 start ---------------------");
cmd1.Transaction = tr;
cmd1.CommandText = "select Content from DX_JKRZ where id=1";
var count = cmd1.ExecuteScalar();
Console.WriteLine(count);
//
cmd1.CommandText = "update DX_JKRZ set CONTENT='xxxxx' where id=1";
cmd1.ExecuteNonQuery();
//
cmd1.CommandText = "select Content from DX_JKRZ where id=1";
count = cmd1.ExecuteScalar();
Console.WriteLine(count);
Thread.Sleep(10000);
Console.WriteLine("-------------Task1 End ---------------------");
tf = true;
});
List<Task> ls = new List<Task>();
ls.Add(t1);
t1.Start();
Console.WriteLine("-------------Main End ---------------------");
while (true)
{
if (sw.ElapsedMilliseconds > 11000)
{
Task.Factory.StartNew(() => {
Task.WaitAll(ls.ToArray());
Console.WriteLine("-------------子任务结束后执行 ---------------------");
});
Console.WriteLine("-------------主任务,不想等了 ---------------------");
tr.Rollback();
conn.Close();
return "超时了";
}
else if (tf)
{
tr.Commit();
conn.Close();
return "操作按时完成了";
}
Console.WriteLine($"======wait{sw.ElapsedMilliseconds}======");
Thread.Sleep(500);
}
}

本文介绍了一种应对第三方平台如微信支付接口超时问题的解决方案。当数据库操作时间过长导致微信支付接口30秒超时时,通过在程序中使用Task异步处理,设置20秒的等待阈值。若Task在20秒内完成,则提交事务并返回成功状态;否则,启动新的Task回滚事务,并向微信平台返回失败状态。
50

被折叠的 条评论
为什么被折叠?



