您的位置:首页 > 数据库

一次提交涉及两个数据库处理

2015-03-25 13:34 148 查看
业务场景:用户下单à付款à扣减库存

问题:当付款成功,扣减库存失败,如何处理。是否可以将这两个事务放在一个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();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐