博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一次提交涉及两个数据库处理
阅读量:5043 次
发布时间:2019-06-12

本文共 2863 字,大约阅读时间需要 9 分钟。

业务场景:用户下单à付款à扣减库存

问题:当付款成功,扣减库存失败,如何处理。是否可以将这两个事务放在一个Transaction中处理?

   

   

 

一、基本概念(Transaction)

什么是事务?事务很任性,只接受成功或失败。在事务包括的范围内,所有操作都是不可分割的单元,当所有操作都成功后事务才算执行成功,否则将进行回滚操作。回忆一下课本中的ACID四大属性(了解即可,复制了书中的描述):

A(Atomicity)原子性:不可再分割的整体,事务中的含义是所有操作都被视为同一不可分割的整体,要么都成功要么都失败。

C(Consistence)一致性:事务开始前和事务结束后,数据库的完整性约束没有被破坏。

I(Isolation)隔离性:当数据正处于事务中时是独占的,不能被其它应用所访问,确保不会读取到脏数据。

D(Durability)持久性:事务一旦提交,则物理存储于数据库中,且在下一次操作前,数据的状态不会被改变。

 

二、解决方案

通过System.TransactionScope 可以实现两个库之间的事务,我们只需要引入System.Transactions.dll 就可以微软提供的强大事务功能了。这里实现的是两个数据库之间的整务,若是要实现数据库和NTFS文件之间的事务,请大家搜索DTC机制,来实现非数据库之间的事务。这部分内容我也正在实践和学习,待理解以后再发出博文与大家探讨。

本实例是连接了本机的两个数据库服务SQLServer2008R2和MySQL,所以需要在工程中引入MySQL.dll。

 以下是实现代码,当DoPayment方法执行成功后,Dostock方法执行失败,此时事务不执行transcope.Complete();语句,在SQLServer中的数据会被回滚。并且在执行Dostock方法时,去查询SQLServer中是查询不到数据的。

namespace ConsoleApplication3{    class Program    {        static string SQLConStr = "server=10.10.60.195,1433;database=tmp;uid=sa;pwd=sa;";        static string MySQLConStr = "server=localhost;uid=root;pwd=root;database=test";        static void Main(string[] args)        {            OrderLogic();        }        public static void OrderLogic()        {            using (TransactionScope transcope = new TransactionScope())            {                //用户付款                //向SQLServer.TPayment表插入一条记录                string sqlText = "insert into TPayment values(156,1,1)";                DoPayment(sqlText);                //扣减库存                //更新MySQL.Product表中stocknum字段                string mysqlText = "update Product set stocknum=stocknum-5 where id=1";                DoStock(mysqlText);                transcope.Complete();            }        }        public static void DoPayment(string sqlText)        {            SqlConnection conn = null;            SqlCommand com = null;            try            {                conn = new SqlConnection(SQLConStr);                conn.Open();                com = new SqlCommand(sqlText, conn);                com.ExecuteNonQuery();            }            catch            {            }            finally            {                if (com != null)                    com.Dispose();                if (conn != null)                    conn.Close();            }        }        public static void DoStock(string sqlText)        {            MySqlConnection conn = null;            MySqlCommand com = null;            try            {                conn = new MySqlConnection(MySQLConStr);                conn.Open();                com = new MySqlCommand(sqlText, conn);                com.ExecuteNonQuery();            }            catch            {            }            finally            {                if (com != null)                    com.Dispose();                if (conn != null)                    conn.Close();            }        }    }}

 

转载于:https://www.cnblogs.com/vinzhou/p/4365460.html

你可能感兴趣的文章
Symfony翻译教程已开课
查看>>
TensorFlow2.0矩阵与向量的加减乘
查看>>
NOIP 2010题解
查看>>
javascript中的each遍历
查看>>
String中各方法多数情况下返回新的String对象
查看>>
浅谈tcp粘包问题
查看>>
UVA11524构造系数数组+高斯消元解异或方程组
查看>>
排序系列之——冒泡排序、插入排序、选择排序
查看>>
爬虫基础
查看>>
jquery.lazyload延迟加载图片第一屏问题
查看>>
HDU 1011 Starship Troopers (树形DP)
查看>>
手把手教你写DI_1_DI框架有什么?
查看>>
.net常见的一些面试题
查看>>
OGRE 源码编译方法
查看>>
上周热点回顾(10.20-10.26)
查看>>
C#正则表达式引发的CPU跑高问题以及解决方法
查看>>
云计算之路-阿里云上:“黑色30秒”走了,“黑色1秒”来了,真相也许大白了...
查看>>
APScheduler调度器
查看>>
设计模式——原型模式
查看>>
【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.1.CSS框架和其他功能
查看>>