基于TransactionScope类的分布式隐式事务
System.Transactions 命名空间中除了上一节中提到的基于 Transaction 类的显式编程模型,还提供使用 TransactionScope 类的隐式编程模型,它与显示编程模型相比,更加方便简单,它也是MSDN中建议使用的编程模型。
下面,我们基于TransactionScope类实现上一节银行转帐的例程。
示例代码:
(1)SqlHelper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using MySql.Data.MySqlClient;
using System.Transactions;
using System.Data;
namespace 事务处理
{
public class SqlHelper
{
public static string GetConnection()
{
string connStr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
return connStr;
}
public static int ExecuteNonQuery(string sql, params MySqlParameter[] parameters)
{
int result = -1;
using (MySqlConnection conn = new MySqlConnection(GetConnection()))
{
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
result = cmd.ExecuteNonQuery();
}
}
return result;
}
public static DataTable ExecuteDataTable(string sql, params MySqlParameter[] parameters)
{
using (MySqlConnection conn = new MySqlConnection(GetConnection()))
{
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
{
using (DataSet ds = new DataSet())
{
da.Fill(ds);
return ds.Tables[0];
}
}
}
}
}
}
}
(2)Bankaccountn.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MySql.Data.MySqlClient;
using System.Data;
using System.Transactions;
namespace 事务处理
{
public class Bankaccountn
{
public Bankaccountn(string bankaccountnId)
{
string sql = @"SELECT * FROM Bankaccountn WHERE BankaccountnId=@BankaccountnId;";
DataTable dt = SqlHelper.ExecuteDataTable(sql, new MySqlParameter("@BankaccountnId", bankaccountnId));
if (dt.Rows.Count <= 0)
{
throw new Exception("账户不存在!");
}
else if (dt.Rows.Count > 1)
{
throw new Exception("异常信息:有重名的账户存在!");
}
else
{
this.bankaccountnId = dt.Rows[0]["BankaccountnId"] as string;
this.UserName = dt.Rows[0]["UserName"] as string;
this.Balance = Convert.ToDecimal(dt.Rows[0]["Balance"]);
}
}
private string bankaccountnId;
public string UserName
{
get;
private set;
}
public decimal Balance
{
get;
private set;
}
protected int Update()
{
string sql = @"UPDATE bankaccountn SET UserName = @UserName,Balance = @Balance
WHERE BankaccountnId= @BankaccountnId;";
return SqlHelper.ExecuteNonQuery(sql, new MySqlParameter("@BankaccountnId", this.bankaccountnId), new MySqlParameter("@UserName", this.UserName), new MySqlParameter("@Balance", this.Balance));
}
public void Epend( decimal money)
{
this.Balance -= money;
this.Update();
}
public void Income(decimal money)
{
this.Balance += money;
this.Update();
}
public bool HiddenTransferOfAccount(string incomeBankaccountnId, decimal money)
{
bool result = true;
using (TransactionScope scope = new TransactionScope())
{
try
{
Bankaccountn incomeBankaccountn = new Bankaccountn(incomeBankaccountnId);
incomeBankaccountn.Income(money); //收款账户入账
this.Epend(money); //付款账户支出
scope.Complete();
}
catch (Exception ex)
{
//这里写做异常信息的记录的代码
result = false;
}
}
return result;
}
}
}
(3)测试代码
Bankaccountn one = new Bankaccountn("6666660123456789");
if (one.HiddenTransferOfAccount("6666669876543210", 200M))
{
Response.Write("<script>alert('转账成功')</script>");
}
else
{
Response.Write("<script>alert('转账失败')</script>");
}
代码分析:
使用TransactionScope 之后,事务管理器会 预执行代码,直至Complete()处,如果过程没有出错,这通知事务管理器去提交,如果错误就不提交,保证了整个执行过程的一致性。
但,在使用隐式编程模型时应注意以下几点:
1)要确保参与事务的资源(如连接的打开等)的全登记放在TransactionScope 实例化对象之后,调用Complete()方法之前。
2)从TransactionScope 实例化到调用Complete()方法之间的代码,不要吃掉异常。
using (TransactionScope scope = new TransactionScope())
{
try
{
//要确保参与事务的资源全部登记在这个位置(如连接的打开等)
Bankaccountn incomeBankaccountn = new Bankaccountn(incomeBankaccountnId);
incomeBankaccountn.Income(money); //收款账户入账
this.Epend(money); //付款账户支出
scope.Complete();
}
catch (Exception ex)
{
//捕获异常要在这个位置
result = false;
}
}
基于TransactionScope类的分布式隐式事务的更多相关文章
- 基于 Transaction 类的分布式显式事务
自.NET2.0以来增加了System.Transactions命名空间,为.NET应用程序带来了一个新的事务编程模型. 这个命名空间提供了几个依赖的TransactionXXX类.Transacti ...
- (4.19)sql server中的事务模式(隐式事务,显式事务,自动提交事务)
(4.19)sql server中的事务模式(隐式事务,显式事务,自动提交事务) 1.概念:隐式事务,显式事务,自动提交事务 2.操作:如何设置事务模式 3.存储过程中的事务 XACT_ABORT 1 ...
- SQL Server显式事务与隐式事务
事务是单个的工作单元.如果某一事务成功,则在该事务中进行的所有数据修改均会提交,成为数据库中的永久组成部分.如果事务遇到错误且必须取消或回滚,则所有数据库修改均被清除. SQL Server中有一下几 ...
- 1067: spark.components:NavigatorContent 类型值的隐式强制指令的目标是非相关类型 String
1.错误描写叙述 此行的多个标记: -workId -1067: spark.components:NavigatorContent 类型值的隐式强制指令的目标是非相关类型 String. 2.错误原 ...
- SQLServer之创建隐式事务
隐式事务创建注意事项 IMPLICIT_TRANSACTIONS为 ON 时,系统处于“隐式”事务模式. 这意味着如果 @@TRANCOUNT = 0,下列任一 Transact-SQL 语句都会开始 ...
- MYSQL中默认隐式事务及利用事务DML
一:默认情况下,MySQL采用autocommit模式运行.这意味着,当您执行一个用于更新(修改)表的语句之后,MySQL立刻把更新存储到磁盘中.默认级别为不可重复读. 二:会造成隐式提交的语句以下语 ...
- C++ 隐式类类型转换和转换操作符
隐式类类型转换 C++语言定义了内置类型之间的几个自动转换.也可以定义如何将其他类型的对象隐式转换为我们的类类型,或将我们的类类型的对象隐式转换为其他类型.为了定义到类类型的隐式转换,需要定义合适的构 ...
- 基于Selenium2+Java的UI自动化(8)- 显式等待和隐式等待
一.隐式等待 package com.automation.waits; import java.util.concurrent.TimeUnit; import org.openqa.seleniu ...
- 读书笔记 effective c++ Item 41 理解隐式接口和编译期多态
1. 显示接口和运行时多态 面向对象编程的世界围绕着显式接口和运行时多态.举个例子,考虑下面的类(无意义的类), class Widget { public: Widget(); virtual ~W ...
随机推荐
- PAT《数据结构学习与实验指导》实验项目集 2-05 2-06 2-07 2-08
题目地址:here pat 2-05 求集合数据的均方差 没什么可说的,大水题 #include<cstdio> #include<cmath> int main() { in ...
- 调用OpenCVSharp进行拍照
一.核心代码: using OpenCvSharp; using System; using System.Collections.Generic; using System.IO; using Sy ...
- SHELL pv uv 统计事例
#!/bin/sh #statistics newplive logs SOURCELOGS=$ ];then echo echo "please input file!" ech ...
- resultType、resultMap
resultType: 作用: 将查询结果按照sql列名pojo属性名一致性映射到pojo中. 场合: 常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用re ...
- Spring学习笔记一:基础概念
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6774310.html 一:Spring是什么 Spring的主要作用是作为对象的容器. 传统编程中,我们 ...
- Java多线程之ReadWriteLock读写锁简介与使用教程
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6558073.html 普通的锁在对某一内容加锁后,其他线程是不能访问的.但是我们要考虑这种情况:如果当前加锁 ...
- JavaSE入门学习7:Java基础语法之语句(下)
继续接着Java基础语法来:JavaSE入门学习5:Java基础语法(一)和JavaSE入门学习6:Java基础语法(二). 语句 Java经常使用的3种循环:while.do...while,for ...
- Excel分数、小数、身份证的录入
身份证输入: 方法1:将单元格格式设置为文本,在输入数据 方法2:在输入之前输入英文状态下的单引号在输入数据 分数输入: 办法1:0[空格]数字/数字,如:0 1/3 办法2:将需要输入数据的区域设置 ...
- Servlet学习(一)
Servlet的运行过程 Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后: ①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象.如果是,则直 ...
- 在QTableView中某列中添加Button的导致滚动条滚动的时候消失的问题
之前在项目上需要在表格中加入Button是按照以下两个文章的做法: http://www.cnblogs.com/li-peng/p/3961843.html http://www.cnblogs.c ...