读书人

事宜参与1

发布时间: 2012-11-06 14:07:00 作者: rapoo

事务参与1

??? 这不是关于资源事务算法(实现)的文章,只是研究资源事务协作过程中,各种资源如何参与事务的(这是借用artech关于事务的文章,不过这里主要还是指数据库)。这里稍微提一下,可能一个业务的完成,需要多个资源或者服务的协作,但是任何服务到达底层依然无外乎资源的访问,这是一个树形结构,而根节点即是业务发起者,所以下面谈到参与者的时候一般泛指资源参与事务。
??? 对于单个资源,事务控制可以显式调用类似BeginTransaction开始事务,然后提交或者回滚;但是如果需要多个资源,他们每个都有自己的资源管理方式和事务控制方式,怎样让他们协作,类似于一个资源一样完整的完成一项业务呢。这里需要单独提出事务管理器概念,从artech文章可以看到,事务管理器负责协调资源以便提供事务支持,但是事务管理器只是使用资源相应的资源管理器来协调资源,而真正实现事务操作或者事务算法的实现都是依赖资源自身的构造。
??? 在这里,自己的理解有些模棱两可。事务管理器的概念问题,因为每个资源都有自己一套事务管理的方式,了解数据库的人都知道,数据库本身都提供事务支持,也就是说资源管理器本身就具备事务管理能力。而且事务本身就是资源管理器的一部分。自己觉得这里提到的事务管理器是一个纯粹的事务协调控制器,即他会协调那些能够提供事务支持的资源以便在业务层面上提供事务支持,但是他不会具体管理资源本身的事务,而且使用每个资源提供的相应的事务控制方式来完成整体性事务。所以本文接下来提到的事务管理器更多的是指高层次的事务协调控制器。
??? 对于单个资源的访问操作,使用资源管理器的事务控制能力基本可以胜任。从数据库里面可以明显的看到。对于多个资源的访问操作,就没那么简单了。首先其中的任何一个资源的访问操作(下面简称参与者),他在进入操作之前,会检查上下文中是否存在上下文事务,如果存在,即把资源相应的资源管理器注册到当前上下文里面,然后继续操作。这个过程中,任何参与者的提交和回滚都会影响到当前上下文事务的其他参与者,保证要不全部提交,要不全部回滚,具体的提交机制可能略有不同,这个可以参照artech为博客文章。
??? 上面提到事务参与者在操作之前都会检查当前上下文事务,然后决定是否需要把自己的资源管理器注册到上下文事务当中。检查当前上下文事务容易,在C#里面,Transaction.Current即是当前上下文事务。至于注册资源管理器,Transaction.Current对于不同的资源管理器提供三个不同的注册函数,

namespace System.Data.SQLite{ using System; using System.Data; using System.Data.Common; using System.Transactions; internal class SQLiteEnlistment : IEnlistmentNotification { internal SQLiteTransaction _transaction; internal Transaction _scope; internal bool _disposeConnection; internal SQLiteEnlistment(SQLiteConnection cnn, Transaction scope) { _transaction = cnn.BeginTransaction(); _scope = scope; _scope.EnlistVolatile(this, System.Transactions.EnlistmentOptions.None); } private void Cleanup(SQLiteConnection cnn) { if (_disposeConnection) cnn.Dispose(); _transaction = null; _scope = null; } #region IEnlistmentNotification Members public void Commit(Enlistment enlistment) { SQLiteConnection cnn = _transaction.Connection; cnn._enlistment = null; try { _transaction.IsValid(true); _transaction.Connection._transactionLevel = 1; _transaction.Commit(); enlistment.Done(); } finally { Cleanup(cnn); } } public void InDoubt(Enlistment enlistment) { enlistment.Done(); } public void Prepare(PreparingEnlistment preparingEnlistment) { if (_transaction.IsValid(false) == false) preparingEnlistment.ForceRollback(); else preparingEnlistment.Prepared(); } public void Rollback(Enlistment enlistment) { SQLiteConnection cnn = _transaction.Connection; cnn._enlistment = null; try { _transaction.Rollback(); enlistment.Done(); } finally { Cleanup(cnn); } } #endregion }}

?

??? 至于sqlite的数据库事务实现,即DbTransaction的实现,相对简单得多,即在响应的函数里面执行sqlite的事务开始、提交、回滚命令。这个跟postsql基本没有太大的出入,postsql的数据库事务的实现基本也是执行数据库响应的命令来实现。
??? 对于postsql的相应的驱动实现,比这个复杂。他调用的是EnlistPromotableSinglePhase函数,实现的是可提升的单阶段登记 (PSPE) 登记具有内部事务的资源管理器。目前对于PSPE在postsql中的实现不是很了解。

?? 待续。。。?

?

引用

System.Data.SQLite?(http://sqlite.phxsoftware.com/)

?

实现资源管理器(http://msdn.microsoft.com/zh-cn/library/ms229975%28v=VS.90%29.aspx)

?

读书人网 >编程

热点推荐