一次提交涉及两个数据库处理
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中是查询不到数据的。
问题:当付款成功,扣减库存失败,如何处理。是否可以将这两个事务放在一个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(); } } } }
相关文章推荐
- 如何将一个表单同时提交到两个地方处理
- ASP.NET 独占操作方法,防止用户反复提交造成数据库处理失败
- 【原】was的一次数据库连接不了的处理记录
- SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理
- SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理
- 如何将一个表单同时提交到两个地方处理
- 通达OA 一次数据库报错问题的处理
- jsp中不同提交方式的中文乱码处理方法及数据库乱码处理方法
- 一次数据库不繁忙时一条sql语句2个执行计划导致业务超时的故障处理
- 关于脏数据比如说,有两个用户A,B同时操作数据库,A开始了一个事务,修改了某行,但还未提交,这个时
- 一次涉及两个大表关联的优化
- 如何实现将数据同时保存到两个数据表,使得同一次提交多个文件的文件ID号相同
- 一次web 服务器无法连接上oracle 数据库的故障处理
- struts2 提交一次重复访问两次数据库
- 如何将一个表单同时提交到两个地方处理
- 在一个form用一个SUBMIT(或button)分别提交到两个处理表单页面的代码
- awk 如何处理两个文件,实现类似数据库表连接的操作
- awk 如何处理两个文件,实现类似数据库表连接的操作
- 记一次数据库无法增删改趋于HANG住状态的故障诊断和处理
- 记一次手误造成mongo数据库主副集全部变成的副集的处理 推荐