JDO事务介绍
前言
Transaction 负责维护JDO数据的完整性。它有下面几种特性:
l 不可分性:这一特性代表一个事务(Transaction)在对数据库进行操作的时候,要么全部执行要么全部失败,它不可能只执行一部分操作。
l 一致性:它保持了数据库数据的一致性。
l 独立性: 每一个事务都是独立的。也就是说在你读写事务中的持久化对象的时候它是不可能被另一个相关的事务操作的。
l 持久使用:一个事务的生命周期是很长的,只要数据存储服务没有停止它就可以一直存在。
以上所描述的Transaction的特性是非常重要的,为了便于理解我来举一个例子:
假设你要作一个银行的系统,你要实现这样一个功能,那就是在用户之间进行转帐,这个程序大致的样子入下:
public void transferFunds (User from, User to, double amnt)
{
//资金转出
from.decrementAccount (amnt);
//资金转入
to.incrementAccount (amnt);
}
好了,根据上面的例子,现在假设有一个用户A要给用户B转帐1000块钱。那么你可以用上面的方法,给它传3格参数,from:A,to:B,amnt:1000。首先,你从用户A那里转出了1000块钱,这是忽然出了问题程序无法远行了(比如出现异常或者干脆就是硬件有毛病了)你的程序没有执行完,也就是说,用户B的账上并没有转入那笔钱。呵呵,1000块钱就这样不见了,为什么呢?因为你的数据没有同步,你没有使用事务。如果上面的转帐操作的两个步骤实在同一个事务中的话,那么就不会出现这个问题,要么一次性从这里转出再转入道另一个帐户,要么两个的帐户都保持不变。
1. 事务类型
事务处理类型有两个主要的类型:数据库的事务处理(或者叫消极的业务处理“Pessimistic”)还有积极(Opessimistic)的事务处理。我们不能简单的从字面的意思来区分两者的优劣,他们各有个的优缺点。
消极事务处理会在事务进行的时候将记录锁定放置其他的事务使用。这样可以有效的避免事务之间的冲突但是它同时也带来了对数据库资源的消耗,而且这还有可能造成记录的死锁。而解决死锁的问题要依赖数据库自身的处理机制。
积极事务处理比起消极事务处理消耗的资源要小,但是稳定性相对较差。因为积极的事务处理不会锁定记录这样就会出现多个事务同时处理同一个记录的情况,如果两个事务同时更新同一个记录的话就会带来事务处理之间的冲突。
2. JDO事务接口
Transaction接口负责控制JDO中的事务,它有一系列的getter,setter方法和标准的事务划分方法以及判断当前运行的事务的方法组成。
public boolean getNontransactionalRead ();
public void setNontransactionalRead (boolean read);
public boolean getNontransactionalWrite ();
public void setNontransactionalWrite (boolean write);
public boolean getRetainValues ();
public void setRetainValues (boolean retain);
public boolean getRestoreValues ();
public void setRestoreValues (boolean restore);
public boolean getOptimistic ();
public void setOptimistic (boolean optimistic);
public Synchronization getSynchronization ();
public void setSynchronization (Synchronization synch);
Transaction的 NonTransactionalRead, NonTransactionalWrite, RetainValues, RestoreValues, 和Optimistic对应PersistenceManagerFactory中相应的方法。最后一个Synchronization方法使你能够访问javax.transaction.Synchronization,这样你就可以扩展这个方法实现自己的commit或rollback。
public void begin ();
public void commit ();
public void rollback ();
上面的3个方法从字面上我们就可以,begin开始一个事务,commit向数据库提交数据,rollback回滚数据。如果commit的时候出现异常JDO会自动回滚数据。
public boolean isActive ();
上面的方法返回当前事务是否为活动的事务。
现在我们把上面那个银行转帐的例子使用Transaction来处理:
public void transferFunds (User from, User to, double amnt)
{
PersistenceManager pm = JDOHelper.getPersistenceManager (from);
Transaction trans = pm.currentTransaction ();
trans.begin ();
try
{
from.decrementAccount (amnt);
to.incrementAccount (amnt);
trans.commit ();
}
catch (JDOFatalException jfe) // 这种情况JDO会自动回滚数据
{
throw jfe;
}
catch (RuntimeException re) // 其他异常通过调研rollback回滚
{
trans.rollback ();
throw re;
}
}