`

使用castle的自动事务控制

阅读更多

直接使用castle的事务控制需要如下几步

1. 配置文件中要求isTransactional="true" 属性,如

xml 代码
  1. <component id="Test" service="wygl.service.test.ITest, wygl.service" 
  2. type="wygl.service.test.TestImpl, wygl.service" lifestyle="Singleton" 
  3. isTransactional="true" />  

2. 必须在容器中注册TransactionFacility ,配置文件片段如下

xml 代码
  1. <facility id="transaction" 
  2. type="Castle.Facilities.AutomaticTransactionManagement.TransactionFacility, 
  3. Castle.Facilities.AutomaticTransactionManagement">facility>  

3. 必须在容其中注册一个实现 Castle.Services.Transaction.ITransactionManager 接口的组件,下面时castle源码中的一个实现

c# 代码
  1. // Copyright 2004-2006 Castle Project - http://www.castleproject.org/   
  2. //    
  3. // Licensed under the Apache License, Version 2.0 (the "License");   
  4. // you may not use this file except in compliance with the License.   
  5. // You may obtain a copy of the License at   
  6. //    
  7. //     http://www.apache.org/licenses/LICENSE-2.0   
  8. //    
  9. // Unless required by applicable law or agreed to in writing, software   
  10. // distributed under the License is distributed on an "AS IS" BASIS,   
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   
  12. // See the License for the specific language governing permissions and   
  13. // limitations under the License.   
  14.   
  15. namespace Castle.Services.Transaction   
  16. {   
  17.     using System;   
  18.     using System.Collections;   
  19.     using System.ComponentModel;   
  20.   
  21.     using Castle.Core.Logging;   
  22.   
  23.     /// <summary></summary>   
  24.     /// TODO: Ensure this class is thread-safe   
  25.     ///    
  26.     public class DefaultTransactionManager : MarshalByRefObject, ITransactionManager   
  27.     {   
  28.         private static readonly object TransactionCreatedEvent = new object();   
  29.         private static readonly object ChildTransactionCreatedEvent = new object();   
  30.         private static readonly object TransactionCommittedEvent = new object();   
  31.         private static readonly object TransactionRolledbackEvent = new object();   
  32.         private static readonly object TransactionDisposedEvent = new object();   
  33.   
  34.         private EventHandlerList events = new EventHandlerList();   
  35.         private ILogger logger = new NullLogger();   
  36.         private Stack transactions = new Stack(5);   
  37.   
  38.         public DefaultTransactionManager()   
  39.         {   
  40.         }   
  41.   
  42.         public ILogger Logger   
  43.         {   
  44.             get { return logger; }   
  45.             set { logger = value; }   
  46.         }  
  47.  
  48.         #region MarshalByRefObject   
  49.   
  50.         public override object InitializeLifetimeService()   
  51.         {   
  52.             return null;   
  53.         }  
  54.  
  55.         #endregion  
  56.  
  57.         #region ITransactionManager Members   
  58.   
  59.         public virtual ITransaction CreateTransaction(TransactionMode transactionMode, IsolationMode isolationMode)   
  60.         {   
  61.             if (transactionMode == TransactionMode.Unspecified)   
  62.             {   
  63.                 transactionMode = ObtainDefaultTransactionMode(transactionMode);   
  64.             }   
  65.   
  66.             CheckNotSupportedTransaction(transactionMode);   
  67.   
  68.             if (CurrentTransaction == null &&    
  69.                 (transactionMode == TransactionMode.Supported ||    
  70.                  transactionMode == TransactionMode.NotSupported))   
  71.             {   
  72.                 return null;   
  73.             }   
  74.   
  75.             StandardTransaction transaction = null;   
  76.   
  77.             if (CurrentTransaction != null)   
  78.             {   
  79.                 if (transactionMode == TransactionMode.Requires || transactionMode == TransactionMode.Supported)   
  80.                 {   
  81.                     transaction = (CurrentTransaction as StandardTransaction).CreateChildTransaction();   
  82.   
  83.                     RaiseChildTransactionCreated(transaction, transactionMode, isolationMode);   
  84.   
  85.                     logger.Debug("Child Transaction {0} created", transaction.GetHashCode());   
  86.                 }   
  87.             }   
  88.   
  89.             if (transaction == null)   
  90.             {   
  91.                 transaction = new StandardTransaction(   
  92.                     new TransactionDelegate(RaiseTransactionCommitted),    
  93.                     new TransactionDelegate(RaiseTransactionRolledback) );   
  94.   
  95.                 RaiseTransactionCreated(transaction, transactionMode, isolationMode);   
  96.   
  97.                 logger.Debug("Transaction {0} created", transaction.GetHashCode());   
  98.             }   
  99.   
  100.             transaction.Logger = logger.CreateChildLogger( transaction.GetType().FullName );   
  101.   
  102.             transactions.Push(transaction);   
  103.   
  104.             return transaction;   
  105.         }   
  106.   
  107.         public event TransactionCreationInfoDelegate TransactionCreated   
  108.         {   
  109.             add { events.AddHandler(TransactionCreatedEvent, value); }   
  110.             remove { events.RemoveHandler(TransactionCreatedEvent, value); }   
  111.         }   
  112.   
  113.         public event TransactionCreationInfoDelegate ChildTransactionCreated   
  114.         {   
  115.             add { events.AddHandler(ChildTransactionCreatedEvent, value); }   
  116.             remove { events.RemoveHandler(ChildTransactionCreatedEvent, value); }   
  117.         }   
  118.   
  119.         public event TransactionDelegate TransactionCommitted   
  120.         {   
  121.             add { events.AddHandler(TransactionCommittedEvent, value); }   
  122.             remove { events.RemoveHandler(TransactionCommittedEvent, value); }   
  123.         }   
  124.   
  125.         public event TransactionDelegate TransactionRolledback   
  126.         {   
  127.             add { events.AddHandler(TransactionRolledbackEvent, value); }   
  128.             remove { events.RemoveHandler(TransactionRolledbackEvent, value); }   
  129.         }   
  130.   
  131.         public event TransactionDelegate TransactionDisposed   
  132.         {   
  133.             add { events.AddHandler(TransactionDisposedEvent, value); }   
  134.             remove { events.RemoveHandler(TransactionDisposedEvent, value); }   
  135.         }   
  136.   
  137.         public virtual ITransaction CurrentTransaction   
  138.         {   
  139.             get  
  140.             {   
  141.                 if (transactions.Count == 0)   
  142.                 {   
  143.                     return null;   
  144.                 }   
  145.                 return transactions.Peek() as ITransaction;   
  146.             }   
  147.         }   
  148.   
  149.         public virtual void Dispose(ITransaction transaction)   
  150.         {   
  151.             if (transaction == null)   
  152.             {   
  153.                 throw new ArgumentNullException("transaction""Tried to dispose a null transaction");   
  154.             }   
  155.   
  156.             lock(transactions)   
  157.             {   
  158.                 if (CurrentTransaction != transaction)   
  159.                 {   
  160.                     throw new ArgumentException("transaction""Tried to dispose a transaction that is not on the current active transaction");   
  161.                 }   
  162.   
  163.                 transactions.Pop();   
  164.             }   
  165.   
  166.             if (transaction is IDisposable)   
  167.             {   
  168.                 (transaction as IDisposable).Dispose();   
  169.             }   
  170.   
  171.             RaiseTransactionDisposed(transaction);   
  172.   
  173.             logger.Debug("Transaction {0} disposed successfully", transaction.GetHashCode());   
  174.         }  
  175.  
  176.         #endregion   
  177.   
  178.         protected void RaiseTransactionCreated(ITransaction transaction, TransactionMode transactionMode, IsolationMode isolationMode)   
  179.         {   
  180.             TransactionCreationInfoDelegate eventDelegate = (TransactionCreationInfoDelegate) events[TransactionCreatedEvent];   
  181.                
  182.             if (eventDelegate != null)   
  183.             {   
  184.                 eventDelegate(transaction, transactionMode, isolationMode);   
  185.             }   
  186.         }   
  187.   
  188.         protected void RaiseChildTransactionCreated(ITransaction transaction, TransactionMode transactionMode, IsolationMode isolationMode)   
  189.         {   
  190.             TransactionCreationInfoDelegate eventDelegate = (TransactionCreationInfoDelegate) events[ChildTransactionCreatedEvent];   
  191.                
  192.             if (eventDelegate != null)   
  193.             {   
  194.                 eventDelegate(transaction, transactionMode, isolationMode);   
  195.             }   
  196.         }   
  197.   
  198.         protected void RaiseTransactionDisposed(ITransaction transaction)   
  199.         {   
  200.             TransactionDelegate eventDelegate = (TransactionDelegate) events[TransactionDisposedEvent];   
  201.                
  202.             if (eventDelegate != null)   
  203.             {   
  204.                 eventDelegate(transaction);   
  205.             }   
  206.         }   
  207.   
  208.         protected void RaiseTransactionCommitted(ITransaction transaction)   
  209.         {   
  210.             TransactionDelegate eventDelegate = (TransactionDelegate) events[TransactionCommittedEvent];   
  211.                
  212.             if (eventDelegate != null)   
  213.             {   
  214.                 eventDelegate(transaction);   
  215.             }   
  216.         }   
  217.   
  218.         protected void RaiseTransactionRolledback(ITransaction transaction)   
  219.         {   
  220.             TransactionDelegate eventDelegate = (TransactionDelegate) events[TransactionRolledbackEvent];   
  221.                
  222.             if (eventDelegate != null)   
  223.             {   
  224.                 eventDelegate(transaction);   
  225.             }   
  226.         }   
  227.   
  228.         protected virtual TransactionMode ObtainDefaultTransactionMode(TransactionMode transactionMode)   
  229.         {   
  230.             return TransactionMode.Requires;   
  231.         }   
  232.   
  233.         private void CheckNotSupportedTransaction(TransactionMode transactionMode)   
  234.         {   
  235.             if (transactionMode == TransactionMode.NotSupported &&    
  236.                 CurrentTransaction != null &&    
  237.                 CurrentTransaction.Status == TransactionStatus.Active)   
  238.             {   
  239.                 String message = "There is a transaction active and the transaction mode " +    
  240.                     "specified explicit says that no transaction is supported for this context";   
  241.   
  242.                 logger.Error(message);   
  243.   
  244.                 throw new TransactionException(message);   
  245.             }   
  246.         }   
  247.     }   
  248. }   

4. 需要使用事务控制的类增加属性,例子如下

c# 代码
  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Text;   
  4. using System.Data;   
  5. using wygl.db;   
  6. using wygl.util;   
  7. using wygl.util.Transaction;   
  8.   
  9. namespace wygl.service.test   
  10. {   
  11.     [Castle.Services.Transaction.Transactional]   
  12.     public class TestImpl : ITest   
  13.     {  
  14.           
  15.         #region ITest 成员   
  16.   
  17.         [Castle.Services.Transaction.Transaction(Castle.Services.Transaction.TransactionMode.Requires)]   
  18.         public virtual string execute()   
  19.         {   
  20.             string conString = configs.connString;   
  21.   
  22.             string SQL = "insert into test(name) values ('test') ";   
  23.             int count = wygl.db.OleDbHelper.ExecuteNonQuery(conString,CommandType.Text, SQL);   
  24.   
  25.             SQL = "insert into test1(name) values ('test') ";   
  26.             count = wygl.db.OleDbHelper.ExecuteNonQuery(conString, CommandType.Text, SQL);   
  27.   
  28.             return "ok:" + count.ToString();   
  29.         }  
  30.  
  31.         #endregion   
  32.     }   
  33. }   

 

感谢  thh  的提醒,以后写东西一定注意,免得误导了大家就不好了,呵呵   

上面的内容忘记写一个核心内容,就是 Castle.Facilities.NHibernateIntegration。如果没有使用Castle.Facilities.NHibernateIntegration.Internal.OpenSession(string alias)中的this.EnlistIfNecessary,那么StandardTransaction里的IResource List 是空的,就不会有任何的事务控制产生。

分享到:
评论
5 楼 thh 2007-09-04  
上面的内容忘记写一个核心内容,就是 Castle.Facilities.NHibernateIntegration。如果没有使用Castle.Facilities.NHibernateIntegration.Internal.OpenSession(string alias)中的this.EnlistIfNecessary,那么StandardTransaction里的IResource List 是空的,就不会有任何的事务控制产生。

看了你的文章好多遍,最后还是自己找到问题...
4 楼 honey0371 2007-08-25  
你好我写了一个测试自动事务控制得例子,专门用来测试castle自动事务的,思路是把2条记录插入不同的表中,故意设置第2个插入语句的插入字段的个数错误,就是说表中要插入2个数据,我故意插入一个,运行结果设想是应该是根据自动事务的原理第一个记录也插不进去,但是第一个插入语句竟然可以把数据插入进去,我实在不知道是哪里错误了,请!
[Transaction(TransactionMode.Requires)]
        public void insert()
        {

            try
            {
                string[] strs ={ "insert into yytest1 values('1511','tt')", "insert into yytest values( 'tyut')" };
                Base newbase = new Base();
                newbase.ExecuteSqls2(strs);

            }
            catch (Exception ex)
            {
            //    throw new Exception(ex.Message);


          Console.Write(ex.Message);



            }


        }
3 楼 pignut_wang 2007-06-13  
建议参考一下,我的另外一篇文章
利用castle 动态代理实现自动事务控制
中的源码
2 楼 pignut_wang 2007-06-13  
应该是你的拦截器没有实现
实现这个拦截器,然后增加到组件注册中,应该就可以了
1 楼 chwang 2007-06-12  
请问一下 “Castle.Facilities.AutomaticTransactionManagement.TransactionComponentInspector”的方法“ProcessModel”没有实现 怎么会出现这个异常呢?

相关推荐

    castle.net AOP教程

    在Castle.Net中,AOP主要用于增强对象的行为,比如日志记录、事务管理、性能监视等,这些功能可以被定义为切面,并在运行时自动应用到目标对象的方法上。 首先,让我们深入了解Castle.Net AOP的基础。Castle动态...

    Castle需要用的引用文件

    Castle.NET 是一个强大的开源框架,它为.NET开发者提供了多种功能,包括动态代理、依赖注入(DI)和控制反转(IoC)容器、AOP(面向切面编程)以及元数据等。在“Castle需要用的引用文件”这个主题下,我们主要关注...

    Castle简单实例

    5. **拦截器和AOP(面向切面编程)**:Castle Windsor可以通过Dynamic Proxy提供拦截器功能,让你可以在不修改原有代码的情况下添加日志、事务管理等横切关注点。 6. **组件配置**:通过XML配置文件或者代码配置,...

    Castle 源码 源代码

    通过继承自ActiveRecord基类,类可以自动关联到数据库表,提供CRUD操作。 3. **Castle MonoRail**:这是一款Web应用框架,与ASP.NET MVC类似,但更注重于MVC模式的实现。MonoRail强调控制器的职责分离,提供视图...

    IBatisNet+Castle项目实例

    1. **依赖注入**:使用Castle Windsor来管理应用程序中的对象生命周期,通过配置文件或代码来定义依赖关系,实现服务的自动注入,减少硬编码,提高代码的可读性和可维护性。 2. **数据库访问层**:IBatisNet作为...

    PetShop_Model_DAL.rar_CASTLE_Castle mod_activeRecord_castle d

    接下来,Castle ActiveRecord提供了强大的自动化功能,如自动建立数据库表、索引、外键等,以及自动生成CRUD(创建、读取、更新、删除)操作。只需简单地调用类的方法,即可完成对数据库的操作,无需编写复杂的SQL...

    Castle ActiveRecord 手册

    5. **事务管理**:Castle ActiveRecord支持自动事务管理,可以在方法级别或块级别开启和提交事务,确保数据一致性。你可以使用`NHibernate.ISession`的`BeginTransaction`、`Commit`和`Rollback`方法来控制事务。 6...

    castle-AOP

    - **事务管理**:自动管理数据库事务,确保数据一致性。 - **性能监控**:统计方法执行时间,优化性能瓶颈。 - **安全性**:控制方法访问权限,防止非法访问。 - **缓存**:在方法调用前检查缓存,避免重复计算。 *...

    castle ActiveRecord 源代码

    2. **对象生命周期管理**:Castle ActiveRecord提供了对对象生命周期的控制,如自动持久化、懒加载、级联操作等。这使得开发者可以在不关心具体数据库操作的情况下,实现对象的创建、更新和删除。 3. **事务管理**...

    Castle IOC容器详解

    在软件开发中,IOC(Inversion of Control,控制反转)是一种设计模式,它改变了传统程序中的控制流程,使得应用程序的组件不再自行管理其依赖关系,而是由一个外部容器(如 Castle Windsor)负责管理和注入。...

    Castle-2.5源码

    源码揭示了如何使用 Castle.Proxy 创建代理对象,并自定义拦截器以实现特定逻辑。 三、Castle ActiveRecord Castle ActiveRecord 是一个ORM(对象关系映射)框架,提供了将.NET对象与数据库表之间的映射。在 ...

    Castle官方下载

    4. **Castle MonoRail**:这是一个轻量级的MVC(模型-视图-控制器)Web应用框架,提供了一种更简洁、更可测试的替代ASP.NET Web Forms的方式。MonoRail强调强类型、约定优于配置以及面向行为的编程。 关于"Castle...

    Castle3.0卷2

    这在处理跨切面的关注点时非常有用,例如,可以在方法调用前后添加日志记录或者事务控制。 4. **Castle Windsor Castle**:这是Castle框架的核心,是一个强大的服务定位器,负责管理和调度应用程序中的对象生命周期...

    Castle ActiveRecord 2.0

    Castle ActiveRecord 支持 AOP(面向切面编程)风格的事务管理,可以使用 `TransactionAttribute` 来标记事务边界,或者在代码中使用 `Session.BeginTransaction()` 和 `Session.CommitTransaction()` 手动控制。...

    Castle-bin-net-2.0.rar

    1. **Castle Windsor**:这是一个功能强大的依赖注入容器(IoC/DI Container),它允许开发者通过控制反转和依赖注入来解耦代码,提高代码的可测试性和可维护性。Windsor容器可以管理对象的生命周期,执行自动装配,...

    asp.net mvc2.0 Jquery IbatisNet Castle

    例如,你可以看到如何在MVC控制器中使用IbatisNet执行SQL查询,如何在视图中利用jQuery创建动态效果,以及如何配置和利用Castle Windsor的依赖注入特性。同时,这也有助于理解MVC模式、前端库、ORM工具和DI容器在...

    Castle Reference Documentation

    Castle项目的核心使命是为.NET开发者提供一套强大、灵活且易于使用的轻量级框架,它支持依赖注入(DI)和面向切面编程(AOP),帮助开发人员构建松耦合、可测试且易于维护的应用程序。 1.2. 历史 Castle项目自其...

    使用Castle Windsor和ABP框架中的拦截器进行面向方面的编程

    拦截器可以在方法调用前后执行额外的任务,比如记录日志、性能监控或事务控制。 **ASP.NET Boilerplate**(ABP)是一个基于模块化和分层的.NET开发框架,它基于许多最佳实践和模式,如依赖注入、领域驱动设计和AOP...

    [干货][EMIT]千行代码实现代理式AOP+属性的自动装配 V2.0

    2. 使用Emit动态创建一个代理类型,该类型继承自目标类型,并实现接口`IInterceptor`(如果使用如Castle DynamicProxy这样的库,可能会用到)。 3. 在代理类型的构造函数中,注入必要的依赖(如日志服务)。 4. 为每...

Global site tag (gtag.js) - Google Analytics