COM+时代的自动事务
最近看公司的遗留项目代码,调试的时候发现经常报分布式事务错误,可是整个代码里没有看见开启过事务,于是开始研究,发现了这个.Net Framework1.1时代的产物。
namespace BusinessService { [Transaction(TransactionOption.RequiresNew, Isolation = TransactionIsolationLevel.ReadCommitted)] public class Operation : ServicedComponent, IOperation //public class Operation : MarshalByRefObject, IOperation { private static List<Person> persons = new List<Person>(); private static string dbStr = "Data Source=DESKTOP-PABLR9F;Initial Catalog=MyDB;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"; public Operation() { Console.WriteLine("服务激活..."); } public int AddPerson(Person person) { Console.WriteLine("添加Person..."); var s = persons.FirstOrDefault(x => x.Id == person.Id); if(s==null) { persons.Add(person); ; } else { ; } } [AutoComplete(true)] public void AddPersons() { List<Person> list = new List<Person>(); ; i <= ; i++) { Person p = + i }; list.Add(p); } using (SqlConnection conn = new SqlConnection(dbStr)) { if (conn.State != System.Data.ConnectionState.Open) conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { foreach (var item in list) { string sql = string.Format("insert into student(name,age,lasttime) values( '{0}',{1},'{2}')",item.Name,item.Age,DateTime.Now); cmd.CommandText = sql; cmd.ExecuteNonQuery(); } } } } [AutoComplete(true)] public void AddPersonRange(ArrayList list) { using (SqlConnection conn = new SqlConnection(dbStr)) { if (conn.State != System.Data.ConnectionState.Open) conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { foreach (Person item in list) { string sql = string.Format("insert into student(name,age,lasttime) values( '{0}',{1},'{2}')", item.Name, item.Age, DateTime.Now); cmd.CommandText = sql; cmd.ExecuteNonQuery(); } } } } public Person GetPerson(int id) { Console.WriteLine("获取Person..."); return persons.FirstOrDefault(x => x.Id == id); } public DateTime GetTime() { Console.WriteLine("获取时间:"+DateTime.Now); return DateTime.Now; } } }
让类继承ServicedComponent,这样调用类的方法的时候会自动开启事务
然后在方法上加上[AutoComplete(true)]属性,这样在方法结束的时候会自动结束事务
这个项目是用remoting做的,顺便把这个也看了看
整体框架:
接口层:
namespace BusinessContract { [Serializable] public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public DateTime LastTime { get; set; } } }
服务层:
namespace BusinessService { [Transaction(TransactionOption.RequiresNew, Isolation = TransactionIsolationLevel.ReadCommitted)] public class Operation : ServicedComponent, IOperation //public class Operation : MarshalByRefObject, IOperation { private static List<Person> persons = new List<Person>(); private static string dbStr = "Data Source=DESKTOP-PABLR9F;Initial Catalog=MyDB;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"; public Operation() { Console.WriteLine("服务激活..."); } public int AddPerson(Person person) { Console.WriteLine("添加Person..."); var s = persons.FirstOrDefault(x => x.Id == person.Id); if(s==null) { persons.Add(person); ; } else { ; } } [AutoComplete(true)] public void AddPersons() { List<Person> list = new List<Person>(); ; i <= ; i++) { Person p = + i }; list.Add(p); } using (SqlConnection conn = new SqlConnection(dbStr)) { if (conn.State != System.Data.ConnectionState.Open) conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { foreach (var item in list) { string sql = string.Format("insert into student(name,age,lasttime) values( '{0}',{1},'{2}')",item.Name,item.Age,DateTime.Now); cmd.CommandText = sql; cmd.ExecuteNonQuery(); } } } } [AutoComplete(true)] public void AddPersonRange(ArrayList list) { using (SqlConnection conn = new SqlConnection(dbStr)) { if (conn.State != System.Data.ConnectionState.Open) conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { foreach (Person item in list) { string sql = string.Format("insert into student(name,age,lasttime) values( '{0}',{1},'{2}')", item.Name, item.Age, DateTime.Now); cmd.CommandText = sql; cmd.ExecuteNonQuery(); } } } } public Person GetPerson(int id) { Console.WriteLine("获取Person..."); return persons.FirstOrDefault(x => x.Id == id); } public DateTime GetTime() { Console.WriteLine("获取时间:"+DateTime.Now); return DateTime.Now; } } }
服务端:
static void Main(string[] args) { //IClientChannelSinkProvider clientProvider = new BinaryClientFormatterSinkProvider(); //IServerChannelSinkProvider serverProvider = new BinaryServerFormatterSinkProvider(); //IDictionary dict = new Hashtable(); //dict["port"] = 8080; //dict["name"] = "myServer"; //HttpChannel channel = new HttpChannel(dict, clientProvider, serverProvider); //int port = Convert.ToInt32(ConfigurationManager.AppSettings["port"].ToString()); //HttpChannel channel = new HttpChannel(port); //ChannelServices.RegisterChannel(channel, false); //RemotingConfiguration.RegisterWellKnownServiceType(typeof(Operation), "ServiceOperation", WellKnownObjectMode.SingleCall); RemotingConfiguration.Configure(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, false); Console.WriteLine("服务端启动..."); Console.ReadKey(); }
服务端配置:
<system.runtime.remoting> <!--.net remoting配置的根节点--> <application> <!--包含有关远程应用程序使用及公共的对象信息--> <service> <!--服务器端,用于指定以什么方式公开什么对象--> <wellknown mode="Singleton" type="BusinessService.Operation,BusinessService" objectUri="ServiceOperation"/> <!--与wellknown相对是activated,wellknown表示服务器端激活对象,后者为客户端激活对象--> <!--mode表示如何响应客户端请求,Singleton表示单一实例--> <!--type表示要公开的类型,选择指定类型名称(含名称空间),然后指定类型所属.dll文件--> <!--objectUri表示远程对象访问路径--> </service> <channels> <!--用于指定通道信息,可心同时指定多个通道--> <channel port=" ref="http"> <clientProviders> <formatter ref="binary" /> </clientProviders> </channel> <!--具体的通道信息,port为端口号,ref为引用的通道类型--> <!--.net 框架提供了http与tcp通道--> </channels> </application> </system.runtime.remoting>
客户端:
static void Main(string[] args) { //HttpChannel channel = new HttpChannel(); //ChannelServices.RegisterChannel(channel, false); RemotingConfiguration.Configure(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, false); string serverUrl = ConfigurationManager.AppSettings["serverUrl"].ToString(); IOperation op = (IOperation)Activator.GetObject(typeof(IOperation), serverUrl); Console.WriteLine(op.GetTime()); //Console.ReadLine(); Person person = , Name = }; op.AddPerson(person); Person p = op.GetPerson(); Console.WriteLine(p.Name + ":" + p.Age); List<Person> list = new List<Person>(); ArrayList al = new ArrayList(); ;i<=;i++) { Person p1 = + i }; list.Add(p1); al.Add(p1); } op.AddPersons(); op.AddPersonRange(al); Console.WriteLine("Done"); Console.ReadKey(); }
客户端配置:
<system.runtime.remoting> <application> <client> <wellknown url="http://10.200.80.172:8080/ServiceOperation" type="BusinessContract.IOperation,BusinessContract"/> </client> <!--远程对象访问路径,域名与IP地址都可以--> <channels> <channel ref="http"/> <!--port为0表示客户端不侦听任何端口--> <clientProviders> <formatter ref="binary" /> </clientProviders> <serverProviders> <formatter ref="binary" /> </serverProviders> </channels> </application> </system.runtime.remoting>
要注意的是:需要把程序集设置为[assembly: ComVisible(true)]
还需要对程序集进行签名:
COM+时代的自动事务的更多相关文章
- 利用AOP实现SqlSugar自动事务
先看一下效果,带接口层的三层架构: BL层: public class StudentBL : IStudentService { private ILogger mLogger; private r ...
- Hibernate自动事务揪出的编码不规范
最近重构的项目(Java初学中),Service层一个获取通知记录报错: org.springframework.dao.InvalidDataAccessResourceUsageException ...
- Aop实现SqlSugar自动事务
http://www.cnblogs.com/jaycewu/p/7733114.html
- 在 ASP.NET Core 中自动启用 CAP 事务
本篇文章旨在描述如何在 ASP.NET Core项目中并以一种简便的方式启用CAP事务,因为在我们的示例中都是直接演示比较直观的方式,没有进行封装,有些初学者同学不太会,找到问我如何封装,本篇文章主要 ...
- sql编程篇 (五) 事务
计算机中的事务 编辑 概念 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用 ...
- CI框架--事务
CI框架中事务封装的很完善,使用起来很简单 1.不开启事务 //不开启事务 前两个sql 能够执行成功,第三个执行失败 $this->device_model->addForCamera( ...
- hibernate(九) 二级缓存和事务级别详讲
序言 这算是hibernate的最后一篇文章了,下一系列会讲解Struts2的东西,然后说完Struts2,在到Spring,然后在写一个SSH如何整合的案例.之后就会在去讲SSM,在之后我自己的个人 ...
- SQLite事务管理
事务管理对数据库一致性是至关重要的.数据库实现ACID属性以确保一致性.SQLite依赖于本地文件锁和页日志来实现ACID属性.SQLite只支持扁平事务,并不支持事务嵌套和保存点能力. 1.1 事务 ...
- SqlServer_事务
事务处理是在数据处理时经常遇到的问题,经常用到的方法有以下三种总结整理如下:方法1:直接写入到sql 中在存储过程中使用 BEGIN TRANS, COMMIT TRANS, ROLLBACK TRA ...
随机推荐
- Arria10中PHY的时钟线结构
发送器时钟网络由发送器PLL到发送器通道,它为发送器提供两种时钟 高速串行时钟——串化器的高速时钟 低速并行时钟——串化器和PCS的低速时钟 在绑定通道模式,串行和并行时钟都是由发送器的PLL提供给发 ...
- SDIBT 2345 (3.2.1 Factorials 阶乘)
Description N的阶乘写作N!表示小于等于N的所有正整数的乘积.阶乘会很快的变大,如13!就必须用32位整数类型来存储,70!即使用浮点数也存不下了.你的任务是找到阶乘最后面的非零位.举个例 ...
- 20155205 《Java程序设计》实验四 Android程序设计
20155205 <Java程序设计>实验四 Android程序设计 一.实验内容及步骤 (一) Android Stuidio的安装测试 参考<Java和Android开发学习指南 ...
- share pool 管理机制
Library cache是Shared pool的一部分,它几乎是Oracle内存结构中最复杂的一部分,主要存放shared curosr(SQL)和PLSQL对象(function,procedu ...
- 读《.net设计规范》
一.影响软件品质的影响有哪些?比如性能.可靠性.安全性.依赖性管理等. 二.客户先行的编程——如果让你把自己的程序库提供的功能描述出来,并让一个开发人员在没有看过该程序库的前提下, 根据他认为该程序库 ...
- 基类的析构函数写成virtual虚析构函数
虚函数作用:动态绑定,实现多态效果. 场景问题: 派生类中有资源需要回收,而在编程中采用多态,由基类的指针指向派生类,则在释放的时候,如果基类的析构函数不是virtual,则派生类的析构函数得不到释放 ...
- Python3 安装 PyQt5 -pycharm 环境搭建
执行命令: pip3 install PyQt5 PyQt5+python3+pycharm开发环境配置 1.下载PyQt 官方网站:http://www.riverbankcomputing.c ...
- 《mysql必知必会》学习_sql文件导入数据库_20180724_欢
解决问题1:MySQL中导入sql文件. 步骤1:show databases;#看看我有什么数据库 步骤2:use hh;#我要用hh这个数据库,返回database changed说明打开成功. ...
- HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化
HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...
- 【Win】Clso QR Tool 二维码小工具
一个可以生成并识别二维码的windows小工具,纯绿色.不含糖. 可以通过输入文本生成二维码,或者加载本地图片.剪贴板内的图片,直接解析出二维码内容. 支持自定义LOGO. 下载文件 (当前版本:1. ...