概述:
为了学习事务的管理,实现了如下的一个简单版本的事务管理器,进行实验。该管理器简化了事务管理的各种异常类型的考虑。
对于Transaction 管理
为了实现数据一致性,对于数据库的JDBC编程通常需要在代码中显示的调用Connection方法的事务相关API来完成工作。
常见的代码如下:
在以上的代码中与业务逻辑相关的代码只有一行, 为了简化事务的操作,实现一个简单的事务管理控制。主要提供以下方面的统一控制。
1.使用回调机制简化事务处理的代码
2.增加对事务隔离级别的支持
3.增加事务Timeout的管理,最简单的实现。 尽早发现长事务的操作。
4.对于savepoint的支持
5.实现一种事务传播控制。 如果当前存在事务,就加入该事务中执行,如果没有新建事务,放到事务中实现。
实现了该事务控制管理器后,将Service的代码得到如下的简化:
1. 回调的实现
定义模板类TransactionTemplate
其主要的方法就是提供模板方法对事务处理的代码进行控制:
2. 回调接口的定义非常的简单:
3. 重点Transaction类的实现,管理了Connection对象,事务隔离级别的定义,事务的savepoint控制点,以及对于事务状态的控制。
1) 对于savePoints属性记录了所有的事务的保存点,当service运行抛出Exception时,将进入rollback逻辑,这个时候,rollback方法会查找相应的Exception的保存点,将事务回滚到该保存点。
具体的保存点检查代码如下:
public void addSavepointAndRollbackException(String name, Exception e)
public boolean isSupportSavepoint() throws SQLException{}
private Savepoint addSavePoint(String savepointName) throws SQLException{}
public boolean containsSavepoint() {}
public Savepoint getSavePointByException(Exception e) {}
2) 属性newTrCount主要是用于实现事务的传播控制。当且仅当该值为1时候表示该事务是新创建的一个事务。当一个service运行的时候,如果发现当前的service线程已经有事务对象,那么这个时候就不需要再重新创建事务,只需要将原有的事务对象的计数器加1,那么相应的当该Serice运行完成才将事务减一,从而保证只有最外层的service看到的事务对象是新创建的事务对象,会执行真正的事务操作,而其他嵌套的Service对象,只是对该count进行操作。
提供了如下的三个方法方便控制:
public void addNewService(){
this.newTrCount++;
}
public void completeService(){
this.newTrCount--;
}
public boolean isNewTransaction(){
return this.newTrCount == 1;
}
4. 核心对象TransactionManager 该对象管理了Transaction对象,并且控制着事务的操作。
其代码如下
5. ConnectionManager对象的实现
为了学习事务的管理,实现了如下的一个简单版本的事务管理器,进行实验。该管理器简化了事务管理的各种异常类型的考虑。
对于Transaction 管理
为了实现数据一致性,对于数据库的JDBC编程通常需要在代码中显示的调用Connection方法的事务相关API来完成工作。
常见的代码如下:
- publicvoiddoService(){
- Connectionconnection=getConnection();
- connection.setTransactionIsolation(
- Connection.TRANSACTION_READ_COMMITTED);
- try{
- doBusinessLogic(connection);
- connection.commit();
- }catch(Exceptione){
- connection.rollback();
- }finally{
- connection.close();
- }
- }
在以上的代码中与业务逻辑相关的代码只有一行, 为了简化事务的操作,实现一个简单的事务管理控制。主要提供以下方面的统一控制。
1.使用回调机制简化事务处理的代码
2.增加对事务隔离级别的支持
3.增加事务Timeout的管理,最简单的实现。 尽早发现长事务的操作。
4.对于savepoint的支持
5.实现一种事务传播控制。 如果当前存在事务,就加入该事务中执行,如果没有新建事务,放到事务中实现。
实现了该事务控制管理器后,将Service的代码得到如下的简化:
- privateServiceservice;
- privateDaodao;
- privateTransactionTemplatetransactionTemplate;
- publicvoidservice(finalObjectobj){
- this.trTemplate.executeTransaction(newTransactionCallback(){
- publicObjectdoTransactionEvent(){
- service.doService();
- transactionTemplate.addSavePoint("savepoint1",exception1);
- dao.saveMethod1(obj);
- transactionTemplate.addSavePoint("savepoint2",exception2);
- dao.saveMethod2(obj);
- }
- });
- }
1. 回调的实现
定义模板类TransactionTemplate
其主要的方法就是提供模板方法对事务处理的代码进行控制:
- publicclassTransactionTemplate{
- privateTransactionManagertrManager;
- //thetimeoutmonitorisusedtofindoutalllongtimetransactioninadvance.
- privatebooleanuseTimeoutMonitor=Boolean.TRUE;
- privateLongmaxTime=Long.valueOf(2);
- publicvoidaddSavePoint(StringsavePointName,ExceptionrollbackException){
- this.trManager.addSavePoint(savePointName,rollbackException);
- }
- publicvoidexecuteTransaction(
- TransactionCallbacktransactionCallback,intisolationLevel){
- longstartTime=System.currentTimeMillis();
- Transactiontransaction=null;
- try{
- transaction=trManager.beginTransaction();
- checkTimeout(startTime);
- transaction.setTransactionIsolationLevel(isolationLevel);
- transactionCallback.doTransactionEvent();
- checkTimeout(startTime);
- trManager.commitTransaction(transaction);
- }catch(Exceptione){
- trManager.rollbackTransaction(transaction,e);
- }finally{
- trManager.closeTransaction(transaction);
- }
- }
- /**
- *Ifthetransactionistimeoutthrowatransactiontimeoutexception.
- */
- privatevoidcheckTimeout(longstartTime){
- if(this.useTimeoutMonitor){
- if(isTimeout(startTime)){
- thrownewTransactionTimeoutException();
- }
- }
- }
- privatebooleanisTimeout(longstartTime){
- returnSystem.currentTimeMillis()-startTime>this.maxTime;
- }
- publicvoidexecuteTransaction(TransactionCallbacktransactionCallback){
- this.executeTransaction(transactionCallback,Transaction.DEFAULT_ISOLATION_LEVEL);
- }
- publicLonggetMaxTime(){
- returnmaxTime;
- }
- publicvoidsetMaxTime(LongmaxTime){
- this.maxTime=maxTime;
- }
- }
2. 回调接口的定义非常的简单:
- publicinterfaceTransactionCallback{
- publicObjectdoTransactionEvent();
- }
3. 重点Transaction类的实现,管理了Connection对象,事务隔离级别的定义,事务的savepoint控制点,以及对于事务状态的控制。
- publicclassTransaction{
- publicstaticfinalintREAD_UNCOMMITTED=Connection.TRANSACTION_READ_UNCOMMITTED;
- publicstaticfinalintREAD_COMMITTED=Connection.TRANSACTION_READ_COMMITTED;
- publicstaticfinalintREPEATALB_READ=Connection.TRANSACTION_REPEATABLE_READ;
- publicstaticfinalintSERIALIZE=Connection.TRANSACTION_SERIALIZABLE;
- publicstaticfinalintDEFAULT_ISOLATION_LEVEL=READ_COMMITTED;
- privateMap<Exception,Savepoint>savePoints=newHashMap<Exception,Savepoint>();
- //Thiscountisusedtoimplementthetransactionpropagation
- privateintnewTrCount=1;
- Connectionconnection;
- publicTransaction(Connectionconnection){
- this.connection=connection;
- }
- publicvoidaddNewService(){
- this.newTrCount++;
- }
- publicvoidcompleteService(){
- this.newTrCount--;
- }
- publicbooleanisNewTransaction(){
- returnthis.newTrCount==1;
- }
- /**
- *@returntheconnection
- */
- publicConnectiongetConnection(){
- returnconnection;
- }
- /**
- *@paramconnectiontheconnectiontoset
- */
- publicvoidsetConnection(Connectionconnection){
- this.connection=connection;
- }
- /**
- *@paramtransactionIsolationLevelthetransactionIsolationLeveltoset
- *@throwsSQLException
- */
- publicvoidsetTransactionIsolationLevel(inttransactionIsolationLevel)throwsSQLException{
- this.connection.setAutoCommit(false);
- this.connection.setTransactionIsolation(transactionIsolationLevel);
- }
- publicvoidaddSavepointAndRollbackException(Stringname,Exceptione)
- throwsSQLException{
- Savepointsavepoint=this.addSavePoint(name);
- this.savePoints.put(e,savepoint);
- }
- publicbooleanisSupportSavepoint()throwsSQLException{
- returnthis.getConnection().getMetaData().supportsSavepoints();
- }
- privateSavepointaddSavePoint(StringsavepointName)throwsSQLException{
- returnthis.connection.setSavepoint(savepointName);
- }
- publicbooleancontainsSavepoint(){
- return!this.savePoints.isEmpty();
- }
- publicSavepointgetSavePointByException(Exceptione){
- returnthis.savePoints.get(e);
- }
- }
1) 对于savePoints属性记录了所有的事务的保存点,当service运行抛出Exception时,将进入rollback逻辑,这个时候,rollback方法会查找相应的Exception的保存点,将事务回滚到该保存点。
具体的保存点检查代码如下:
public void addSavepointAndRollbackException(String name, Exception e)
public boolean isSupportSavepoint() throws SQLException{}
private Savepoint addSavePoint(String savepointName) throws SQLException{}
public boolean containsSavepoint() {}
public Savepoint getSavePointByException(Exception e) {}
2) 属性newTrCount主要是用于实现事务的传播控制。当且仅当该值为1时候表示该事务是新创建的一个事务。当一个service运行的时候,如果发现当前的service线程已经有事务对象,那么这个时候就不需要再重新创建事务,只需要将原有的事务对象的计数器加1,那么相应的当该Serice运行完成才将事务减一,从而保证只有最外层的service看到的事务对象是新创建的事务对象,会执行真正的事务操作,而其他嵌套的Service对象,只是对该count进行操作。
提供了如下的三个方法方便控制:
public void addNewService(){
this.newTrCount++;
}
public void completeService(){
this.newTrCount--;
}
public boolean isNewTransaction(){
return this.newTrCount == 1;
}
4. 核心对象TransactionManager 该对象管理了Transaction对象,并且控制着事务的操作。
其代码如下
- publicclassTransactionManager{
- privateConnectionManagerconnectionManager;
- privateThreadLocal<Transaction>transactions=newThreadLocal<Transaction>();
- publicTransactionbeginTransaction(){
- try{
- Transactiontr=this.transactions.get();
- if(tr==null){
- Connectionconnection=connectionManager.getConnection();
- connectionManager.setTransactionActive(true);
- tr=newTransaction(connection);
- this.transactions.set(tr);
- }else{
- tr.addNewService();
- }
- returntr;
- }catch(Exceptione){
- thrownewTransactionException();
- }
- }
- publicvoidcommitTransaction(Transactiontransaction){
- try{
- if(transaction.isNewTransaction()){
- connectionManager.setTransactionActive(false);
- connectionManager.commit(transaction.getConnection());
- }
- }catch(Exceptione){
- thrownewTransactionException();
- }
- }
- publicvoidrollbackTransaction(Transactiontransaction,Exceptione){
- try{
- if(transaction.isNewTransaction()){
- connectionManager.setTransactionActive(false);
- if(transaction.containsSavepoint()){
- Savepointsavepoint=transaction.getSavePointByException(e);
- if(savepoint==null){
- connectionManager.rollback(transaction.getConnection());
- }else{
- connectionManager.rollback(transaction.getConnection(),savepoint);
- }
- }else{
- connectionManager.rollback(transaction.getConnection());
- }
- }
- }catch(Exceptione2){
- thrownewTransactionException();
- }
- }
- publicvoidcloseTransaction(Transactiontransaction){
- try{
- if(transaction.isNewTransaction()){
- this.transactions.remove();
- connectionManager.setTransactionActive(false);
- connectionManager.releaseConnection(transaction.getConnection());
- }else{
- transaction.completeService();
- }
- }catch(Exceptione){
- thrownewTransactionException();
- }
- }
- /**
- *@return
- *@throwsClassNotFoundException
- *@throwsSQLException
- */
- /**
- *@returntheconnectionManager
- */
- publicConnectionManagergetConnectionManager(){
- returnconnectionManager;
- }
- /**
- *@paramconnectionManagertheconnectionManagertoset
- */
- publicvoidsetConnectionManager(ConnectionManagerconnectionManager){
- this.connectionManager=connectionManager;
- }
- publicvoidaddSavePoint(StringsavePointName,ExceptionrollbackException){
- Transactiontr=this.transactions.get();
- if(tr==null){
- tr=this.beginTransaction();
- }
- try{
- if(!tr.isSupportSavepoint()){
- thrownewSavePointNotSupportException();
- }
- tr.addSavepointAndRollbackException(savePointName,rollbackException);
- }catch(Exceptione){
- thrownewTransactionException();
- }
- }
- }
5. ConnectionManager对象的实现
- publicclassConnectionManager{
- privatestaticConnectionManagerconnectionManager=newConnectionManager();
- ThreadLocal<Connection>threadConnection=newThreadLocal<Connection>();
- privateConnectionManager(){}
- publicstaticConnectionManagergetConnectionManager(){
- returnconnectionManager;
- }
- privateBooleanisTransactionActive=Boolean.FALSE;
- publicConnectiongetConnection()throwsClassNotFoundException,SQLException{
- Connectionconnection=this.threadConnection.get();
- if(connection==null){
- connection=(Connection)DriverManager.getConnection(
- "jdbc:sqlserver://10.171.30.11:1433;instanceName=nasa;databaseName=nasa2_SMS_PT;SelectMethod=cursor;characterEncoding=utf-8;autoReconnectForPools=true;autoReconnect=true",
- "sms","sms");
- this.threadConnection.set(connection);
- }
- returnconnection;
- }
- publicvoidreleaseConnection(Connectionconnection)throwsSQLException{
- if(!isTransactionActive){
- threadConnection.remove();
- connection.close();
- }
- }
- publicvoidcommit(Connectionconnection)throwsSQLException{
- if(!isTransactionActive){
- connection.commit();
- }
- }
- publicvoidrollback(Connectionconnection)throwsSQLException{
- if(!isTransactionActive){
- connection.rollback();
- }
- }
- publicvoidrollback(Connectionconnection,Savepointsavepoint)throwsSQLException{
- if(!isTransactionActive){
- connection.rollback(savepoint);
- }
- }
- /**
- *@paramisTransactionFinishedtheisTransactionFinishedtoset
- */
- publicvoidsetTransactionActive(BooleanisTransactionActive){
- this.isTransactionActive=isTransactionActive;
- }
- }