NET事务.docx
《NET事务.docx》由会员分享,可在线阅读,更多相关《NET事务.docx(25页珍藏版)》请在冰豆网上搜索。
NET事务
.net事务1--(SqlTransaction)
目录
1.概述
2.应用程序事务和数据库管理系统事务的区别
1. 论述
2. 数据的迁移
3. 后期的维护
4. 建议
3.代码
1. OperateDataBase类
2. main所在类控制台应用程序
4.应用SqlTransaction时三层架构中的代码分布
5.总结
概述
.net开发程序中,使用事务的方法有4中,分别为:
数据库管理系统中的事务(SQL代码) ;.net中的SqlTransaction;.net中的Com+事务;.net中的TransactionScope。
对于数据库管理系统中的事务和Com+事务,在这里就不讲,主要讲解的为SqlTransaction和TransactionScope,本片博客讲解的是SqlTransaction,下一篇博客讲解TransactionScope,接下了接入我们本片博客的主题:
SqlTransaction。
应用程序事务和数据库管理系统事务的区别
论述
概述中已经讲解了.net开发中实现事务的几种方式,当然,如果我们从另一个角度上看,事务的实现就两种方式:
应用程序事务和数据库管理系统事务。
应用程序事务是在应用程序中通过代码控制事务的开启,数据库管理系统的事务主要是通过书写存储过程来创建的,两种方式都可以实现事务,但是,从数据库的迁移和应用程序后期的维护上说,应用程序事务更好,当然,凑够效率上说,事务写在数据库管理系统上更好,但是从它的缺点和现在计算机的硬件发展来说,显然它的这个优点不太突出了。
数据的迁移
事务写在数据库管理系统上时,如果你想将该数据库(MSSQL)搬迁到Oracle数据库管理系统上,那么其事务(存储过程)可能在Oracle中不兼容(系统提供的方法等不全部一样),但是,如果你将事务写在程序中就不存在这种情况。
后期的维护
用到事务的时候,最简单的也是多个表的操作(一个表的操作没有意义),意思就是说,事务的逻辑性很强,如果我们将事务写在数据库管理系统上,那么开发人员再看程序代码的时候,是无法清楚的了解事务内部的逻辑的,此时矛盾出现了,因为有时,我们维护人员不得不去了解这种逻辑,这样的话,我们还要查看里面相应的T-Sql语句,是一个非常麻烦的过程,但是,如果我们将事务写在应用程序中,那么我们在看代码的过程中就已经把事务中的逻辑了解了,因为应用程序中事务的逻辑是通过应用程序代码
建议
那种不会学哪种,两种都不会,先学数据库中的事务,都会之后,用应用程序中的事务。
代码
OperateDataBase类
[csharp]viewplaincopyprint?
1.using System;
2.using System.Collections.Generic;
3.using System.Linq;
4.using System.Text;
5.using System.Threading.Tasks;
6.using System.Data;
7.using System.Data.SqlClient;
8.using System.Configuration;
9.
10.namespace 事务.普通事务
11.{
12. public class OperateDataBase
13. {
14. #region 创建SqlConnection
15. public SqlConnection CreateSqlConnection() {
16. SqlConnection sqlCon = new SqlConnection(ConfigurationManager .ConnectionStrings ["strCon"].ToString ());
17. sqlCon.Open();
18. return sqlCon;
19. }
20. #endregion
21.
22. #region 添加数据
23. public int Execute(SqlConnection sqlCon,string strSql,SqlTransaction tran) {
24. SqlCommand sqlCmd = new SqlCommand(strSql, sqlCon, tran);
25. return sqlCmd.ExecuteNonQuery();
26. }
27. #endregion
28. }
29.}
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Data;
usingSystem.Data.SqlClient;
usingSystem.Configuration;
namespace事务.普通事务
{
publicclassOperateDataBase
{
#region创建SqlConnection
publicSqlConnectionCreateSqlConnection(){
SqlConnectionsqlCon=newSqlConnection(ConfigurationManager.ConnectionStrings["strCon"].ToString());
sqlCon.Open();
returnsqlCon;
}
#endregion
#region添加数据
publicintExecute(SqlConnectionsqlCon,stringstrSql,SqlTransactiontran){
SqlCommandsqlCmd=newSqlCommand(strSql,sqlCon,tran);
returnsqlCmd.ExecuteNonQuery();
}
#endregion
}
}
main所在类(控制台应用程序)
[csharp]viewplaincopyprint?
1.using System;
2.using System.Collections.Generic;
3.using System.Linq;
4.using System.Text;
5.using System.Threading.Tasks;
6.using System.Data.SqlClient;
7.
8.namespace 事务.普通事务
9.{
10. class Program
11. {
12. static void Main(string[] args)
13. {
14. OperateDataBase operateDataBase = new OperateDataBase();
15. using (SqlConnection sqlCon = operateDataBase.CreateSqlConnection())
16. {
17. //开启事务
18. SqlTransaction tran = sqlCon.BeginTransaction();
19. string strSql1 = "insert into DataTable1(id,name) values(21,'张三')";
20. string strSql2 = "insert into DataTable2(id,name) values(21,'张三')";
21. try
22. {
23. operateDataBase.Execute(sqlCon, strSql1, tran);
24. operateDataBase.Execute(sqlCon, strSql2, tran);
25. //提交事务
26. tran.Commit();
27. }
28. catch (Exception)
29. {
30. //回滚事务
31. tran.Rollback();
32. }
33. }
34.
35. }
36. }
37.}
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Data.SqlClient;
namespace事务.普通事务
{
classProgram
{
staticvoidMain(string[]args)
{
OperateDataBaseoperateDataBase=newOperateDataBase();
using(SqlConnectionsqlCon=operateDataBase.CreateSqlConnection())
{
//开启事务
SqlTransactiontran=sqlCon.BeginTransaction();
stringstrSql1="insertintoDataTable1(id,name)values(21,'张三')";
stringstrSql2="insertintoDataTable2(id,name)values(21,'张三')";
try
{
operateDataBase.Execute(sqlCon,strSql1,tran);
operateDataBase.Execute(sqlCon,strSql2,tran);
//提交事务
tran.Commit();
}
catch(Exception)
{
//回滚事务
tran.Rollback();
}
}
}
}
}
应用SqlTransaction时,三层架构中的代码分布
上面的也讲到过,应用在一张表的事务几乎很少见,大多都是多张表,但是由于SqlTransaction的特殊性,事务的范围在连接对象内,所以,在三层架构中应用该类的时候,应该在B层进行事务的控制,B层给D的东西,多了一个数据库连接对象和事务对象,此时需要注意,数据库连接对象是在D层创建的,只不过他先返回到了B层。
总结
.NET分布式事务2--TransactionScop
目录
1.概述
2.开启DTC服务
1. 方式一
2. 方式二
3.设置MSDTC
4.防火墙设置
5.数据库管理系统设置
6.代码
1. 控制台代码
2. OperateDataBasecs类同一数据库服务器不同数据库
3. OperateDifferentDataBaseServercs不同数据库系统
7.简单原理的介绍
8.总结
概述
SqlTransaction可以解决同一个数据库的事务控制,但是,不能解决不同数据库的事务控制,今天就说一说,这个的解决方法,即:
TransactionScope的应用。
本篇博客的的思路就是先进行一些相应的配置(开启DTC服务,配置MSDTC,配置防火墙,配置数据库管理系统),然后再进行一个实例的展示(代码),最后进行简单原理的介绍和总结。
了解了本篇博客的流程和结构后,接下来就看相应具体的内容吧!
开启DTC服务
方式一
计算机—管理—服务—Distributed(分布式)LinkTrackingClient—属性—开启
方式二
字符命令子界面输入:
netstartmsdtc
设置MSDTC
命令界面输入:
dcomcnfg.exe(或者:
控制面板—管理工具—组件服务)
防火墙设置
有两种方法:
1、直接关闭防火墙(不建议使用,以前数据库连接的时候这样干过);2、进行如下图的设置
数据库管理系统设置
因为要实现多个数据库系统之间事务的控制,所以,数据库系统也需要做相应的设置,具体如下图。
代码
下面是一个简单的Demo,实现了两个功能:
1、同一数据库系统,不同数据库的事务控制;2、不同数据库系统的事务控制。
控制台代码
[csharp]viewplaincopyprint?
1.using System;
2.using System.Collections.Generic;
3.using System.Linq;
4.using System.Text;
5.using System.Threading.Tasks;
6.using System.Transactions;
7.
8.namespace 事务.分布式
9.{
10. class Program
11. {
12. static void Main(string[] args)
13. {
14. #region 同一个数据库服务器,操作不同的数据库
15. //using (TransactionScope tran = new TransactionScope())
16. //{
17. // OperateDataBase operateDataBase = new OperateDataBase();
18. // int i = operateDataBase.Execute1();
19. // int j = operateDataBase.Execute2();
20. // tran.Complete();
21. //}
22. #endregion
23.
24. #region 不同的数据库服务器
25. using (TransactionScope tran = new TransactionScope())
26. {
27.
28. OperateDifferentDataBaseServer operateDifferentDataBaseServer = new OperateDifferentDataBaseServer();
29. int i = operateDifferentDataBaseServer.Execute1();
30. int j = operateDifferentDataBaseServer.Execute2();
31. tran.Complete();
32. }
33. #endregion
34. }
35. }
36.}
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Transactions;
namespace事务.分布式
{
classProgram
{
staticvoidMain(string[]args)
{
#region同一个数据库服务器,操作不同的数据库
//using(TransactionScopetran=newTransactionScope())
//{
//OperateDataBaseoperateDataBase=newOperateDataBase();
//inti=operateDataBase.Execute1();
//intj=operateDataBase.Execute2();
//tran.Complete();
//}
#endregion
#region不同的数据库服务器
using(TransactionScopetran=newTransactionScope())
{
OperateDifferentDataBaseServeroperateDifferentDataBaseServer=newOperateDifferentDataBaseServer();
inti=operateDifferentDataBaseServer.Execute1();
intj=operateDifferentDataBaseServer.Execute2();
tran.Complete();
}
#endregion
}
}
}
OperateDataBase.cs类(同一数据库服务器,不同数据库)
[csharp]viewplaincopyprint?
1.using System;
2.using System.Collections.Generic;
3.using System.Linq;
4.using System.Text;
5.using System.Threading.Tasks;
6.using System.Data;
7.using System.Data.SqlClient;
8.using System.Configuration;
9.
10.namespace 事务.分布式
11.{
12. public class OperateDataBase
13. {
14. private SqlConnection sqlCon1;
15. private SqlConnection sqlCon2;
16. private SqlCommand sqlCom;
17.
18. #region 数据库系统1—数据库1—连接对象
19. private void GetConnection1() {
20. if (sqlCon1 == null)
21. {
22. sqlCon1 = new SqlConnection(ConfigurationManager.ConnectionStrings["strCon1"].ToString());
23. }
24. if (sqlCon1.State == ConnectionState.Closed)
25. {
26. sqlCon1.Open();
27. }
28. }
29. #endregion
30.
31. #region 数据库系统1—数据库2—连接对象
32. private void GetConnection2() {
33. if (sqlCon2 == null)
34. {
35. sqlCon2 = new SqlConnection(ConfigurationManager.ConnectionStrings["strCon2"].ToString());
36. }
37. if (sqlCon2.State == ConnectionState.Closed)
38. {
39. sqlCon2.Open();
40. }
41. }
42. #endregion
43