标签:exce cat 并发 bubuko public src code 测试 lin
简述:项目中回滚的方法很多种,目前我用到的一种是事务回滚。一种是是手动回滚。
事务回滚就是让代码包在一个事务里面,然后所有的代码成功执行后,最后有一个提交的操作。
手动回滚,就是自己写代码处理回滚。
写博客背景:
我在公司负责的支付那块,开始用的事务回滚,将所有的支付逻辑都包在了一个大的事务里面,这样就会导致当有并发的时候,总是发生锁表问题。 然后采取的方案就是把大事务拆分成很多小事务,每个事务里面包含一个唯一的数据库操作逻辑。提交后外面代码写上对上步的回滚操作并放在栈里面,这样当有异常时,就会按照后进先出原则依次回滚。经过测试,成功解决了并发支付问题。 (PS:但是还有一个问题是,对于同一个数据,两个人同时支付会同时走支付代码,这块还没处理好业务并发,之前考虑加锁,但是这样系统就又变成了单线程执行,后面再考虑方案。)
用控制台简单写了一个Demo,计算了一个累加的操作,然后每一步都记录了回滚,每一步异常都会回滚到最初的数据10上面。
目录结构如下:
Program.cs
private static Stack<IRollBack> _rollBack = new Stack<IRollBack>(); private static int Sum = 10; static void Main(string[] args) { try { int Num1 = 3; int Num2 = 5; //定义一个元数据是Sum=10,Num1=3,Num2=5 //第一步: Sum=Sum+Num1 Sum=10+3=13 //第一步回滚: Sum=Sum-Num1 Sum=13-3=10 Sum = Sum + Num1; IRollBack r1 = new Num1RollBack(Sum, Num1); _rollBack.Push(r1); //第二步: Sum=Sum+Num2 Sum=13+5=18 //第二步回滚: Sum=Sum-Num2 Sum=18-5=13 Sum = Sum + Num2; IRollBack r2 = new Num1RollBack(Sum, Num2); _rollBack.Push(r2); Console.WriteLine(Sum); //throw new Exception("测试回滚"); Console.WriteLine("zj..."); Console.ReadKey(); } catch (Exception ex) { RollBack(); } Console.ReadKey(); } public static void RollBack() { IRollBack rollBack = null; while (_rollBack.Count>0) { rollBack = _rollBack.Pop(); Sum=rollBack.RollBack(); } Console.WriteLine(Sum); }
IRollBack.cs
public interface IRollBack { int RollBack(); }
Num1RollBack.cs
public class Num1RollBack : IRollBack { private int _sum, _num1; public Num1RollBack(int sum,int num1) { _sum = sum; _num1 = num1; } public int RollBack() { return _sum - _num1; } }
Num2RollBack.cs
public class Num2RollBack : IRollBack { private int _sum, _num2; public Num2RollBack(int sum, int num2) { _sum = sum; _num2 = num2; } public int RollBack() { return _sum - _num2; } }
一般情况下我们在web中都是操作的数据库,所以回滚接口定义成void即可,然后每个回滚实现接口处理回滚操作。
标签:exce cat 并发 bubuko public src code 测试 lin
原文地址:https://www.cnblogs.com/shuai7boy/p/10185361.html