事务管理(三)——JDBC事务管理的简单实现

概述:
为了学习事务的管理,实现了如下的一个简单版本的事务管理器,进行实验。该管理器简化了事务管理的各种异常类型的考虑。

对于Transaction 管理
为了实现数据一致性,对于数据库的JDBC编程通常需要在代码中显示的调用Connection方法的事务相关API来完成工作。
常见的代码如下:
Java代码 收藏代码
  1. publicvoiddoService(){
  2. Connectionconnection=getConnection();
  3. connection.setTransactionIsolation(
  4. Connection.TRANSACTION_READ_COMMITTED);
  5. try{
  6. doBusinessLogic(connection);
  7. connection.commit();
  8. }catch(Exceptione){
  9. connection.rollback();
  10. }finally{
  11. connection.close();
  12. }
  13. }


在以上的代码中与业务逻辑相关的代码只有一行, 为了简化事务的操作,实现一个简单的事务管理控制。主要提供以下方面的统一控制。
1.使用回调机制简化事务处理的代码
2.增加对事务隔离级别的支持
3.增加事务Timeout的管理,最简单的实现。 尽早发现长事务的操作。
4.对于savepoint的支持
5.实现一种事务传播控制。 如果当前存在事务,就加入该事务中执行,如果没有新建事务,放到事务中实现。

实现了该事务控制管理器后,将Service的代码得到如下的简化:
Java代码 收藏代码
  1. privateServiceservice;
  2. privateDaodao;
  3. privateTransactionTemplatetransactionTemplate;
  4. publicvoidservice(finalObjectobj){
  5. this.trTemplate.executeTransaction(newTransactionCallback(){
  6. publicObjectdoTransactionEvent(){
  7. service.doService();
  8. transactionTemplate.addSavePoint("savepoint1",exception1);
  9. dao.saveMethod1(obj);
  10. transactionTemplate.addSavePoint("savepoint2",exception2);
  11. dao.saveMethod2(obj);
  12. }
  13. });
  14. }


1. 回调的实现
定义模板类TransactionTemplate
其主要的方法就是提供模板方法对事务处理的代码进行控制:
Java代码 收藏代码
  1. publicclassTransactionTemplate{
  2. privateTransactionManagertrManager;
  3. //thetimeoutmonitorisusedtofindoutalllongtimetransactioninadvance.
  4. privatebooleanuseTimeoutMonitor=Boolean.TRUE;
  5. privateLongmaxTime=Long.valueOf(2);
  6. publicvoidaddSavePoint(StringsavePointName,ExceptionrollbackException){
  7. this.trManager.addSavePoint(savePointName,rollbackException);
  8. }
  9. publicvoidexecuteTransaction(
  10. TransactionCallbacktransactionCallback,intisolationLevel){
  11. longstartTime=System.currentTimeMillis();
  12. Transactiontransaction=null;
  13. try{
  14. transaction=trManager.beginTransaction();
  15. checkTimeout(startTime);
  16. transaction.setTransactionIsolationLevel(isolationLevel);
  17. transactionCallback.doTransactionEvent();
  18. checkTimeout(startTime);
  19. trManager.commitTransaction(transaction);
  20. }catch(Exceptione){
  21. trManager.rollbackTransaction(transaction,e);
  22. }finally{
  23. trManager.closeTransaction(transaction);
  24. }
  25. }
  26. /**
  27. *Ifthetransactionistimeoutthrowatransactiontimeoutexception.
  28. */
  29. privatevoidcheckTimeout(longstartTime){
  30. if(this.useTimeoutMonitor){
  31. if(isTimeout(startTime)){
  32. thrownewTransactionTimeoutException();
  33. }
  34. }
  35. }
  36. privatebooleanisTimeout(longstartTime){
  37. returnSystem.currentTimeMillis()-startTime>this.maxTime;
  38. }
  39. publicvoidexecuteTransaction(TransactionCallbacktransactionCallback){
  40. this.executeTransaction(transactionCallback,Transaction.DEFAULT_ISOLATION_LEVEL);
  41. }
  42. publicLonggetMaxTime(){
  43. returnmaxTime;
  44. }
  45. publicvoidsetMaxTime(LongmaxTime){
  46. this.maxTime=maxTime;
  47. }
  48. }


2. 回调接口的定义非常的简单:
Java代码 收藏代码
  1. publicinterfaceTransactionCallback{
  2. publicObjectdoTransactionEvent();
  3. }


3. 重点Transaction类的实现,管理了Connection对象,事务隔离级别的定义,事务的savepoint控制点,以及对于事务状态的控制。

Java代码 收藏代码
  1. publicclassTransaction{
  2. publicstaticfinalintREAD_UNCOMMITTED=Connection.TRANSACTION_READ_UNCOMMITTED;
  3. publicstaticfinalintREAD_COMMITTED=Connection.TRANSACTION_READ_COMMITTED;
  4. publicstaticfinalintREPEATALB_READ=Connection.TRANSACTION_REPEATABLE_READ;
  5. publicstaticfinalintSERIALIZE=Connection.TRANSACTION_SERIALIZABLE;
  6. publicstaticfinalintDEFAULT_ISOLATION_LEVEL=READ_COMMITTED;
  7. privateMap<Exception,Savepoint>savePoints=newHashMap<Exception,Savepoint>();
  8. //Thiscountisusedtoimplementthetransactionpropagation
  9. privateintnewTrCount=1;
  10. Connectionconnection;
  11. publicTransaction(Connectionconnection){
  12. this.connection=connection;
  13. }
  14. publicvoidaddNewService(){
  15. this.newTrCount++;
  16. }
  17. publicvoidcompleteService(){
  18. this.newTrCount--;
  19. }
  20. publicbooleanisNewTransaction(){
  21. returnthis.newTrCount==1;
  22. }
  23. /**
  24. *@returntheconnection
  25. */
  26. publicConnectiongetConnection(){
  27. returnconnection;
  28. }
  29. /**
  30. *@paramconnectiontheconnectiontoset
  31. */
  32. publicvoidsetConnection(Connectionconnection){
  33. this.connection=connection;
  34. }
  35. /**
  36. *@paramtransactionIsolationLevelthetransactionIsolationLeveltoset
  37. *@throwsSQLException
  38. */
  39. publicvoidsetTransactionIsolationLevel(inttransactionIsolationLevel)throwsSQLException{
  40. this.connection.setAutoCommit(false);
  41. this.connection.setTransactionIsolation(transactionIsolationLevel);
  42. }
  43. publicvoidaddSavepointAndRollbackException(Stringname,Exceptione)
  44. throwsSQLException{
  45. Savepointsavepoint=this.addSavePoint(name);
  46. this.savePoints.put(e,savepoint);
  47. }
  48. publicbooleanisSupportSavepoint()throwsSQLException{
  49. returnthis.getConnection().getMetaData().supportsSavepoints();
  50. }
  51. privateSavepointaddSavePoint(StringsavepointName)throwsSQLException{
  52. returnthis.connection.setSavepoint(savepointName);
  53. }
  54. publicbooleancontainsSavepoint(){
  55. return!this.savePoints.isEmpty();
  56. }
  57. publicSavepointgetSavePointByException(Exceptione){
  58. returnthis.savePoints.get(e);
  59. }
  60. }

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对象,并且控制着事务的操作。
其代码如下
Java代码 收藏代码
  1. publicclassTransactionManager{
  2. privateConnectionManagerconnectionManager;
  3. privateThreadLocal<Transaction>transactions=newThreadLocal<Transaction>();
  4. publicTransactionbeginTransaction(){
  5. try{
  6. Transactiontr=this.transactions.get();
  7. if(tr==null){
  8. Connectionconnection=connectionManager.getConnection();
  9. connectionManager.setTransactionActive(true);
  10. tr=newTransaction(connection);
  11. this.transactions.set(tr);
  12. }else{
  13. tr.addNewService();
  14. }
  15. returntr;
  16. }catch(Exceptione){
  17. thrownewTransactionException();
  18. }
  19. }
  20. publicvoidcommitTransaction(Transactiontransaction){
  21. try{
  22. if(transaction.isNewTransaction()){
  23. connectionManager.setTransactionActive(false);
  24. connectionManager.commit(transaction.getConnection());
  25. }
  26. }catch(Exceptione){
  27. thrownewTransactionException();
  28. }
  29. }
  30. publicvoidrollbackTransaction(Transactiontransaction,Exceptione){
  31. try{
  32. if(transaction.isNewTransaction()){
  33. connectionManager.setTransactionActive(false);
  34. if(transaction.containsSavepoint()){
  35. Savepointsavepoint=transaction.getSavePointByException(e);
  36. if(savepoint==null){
  37. connectionManager.rollback(transaction.getConnection());
  38. }else{
  39. connectionManager.rollback(transaction.getConnection(),savepoint);
  40. }
  41. }else{
  42. connectionManager.rollback(transaction.getConnection());
  43. }
  44. }
  45. }catch(Exceptione2){
  46. thrownewTransactionException();
  47. }
  48. }
  49. publicvoidcloseTransaction(Transactiontransaction){
  50. try{
  51. if(transaction.isNewTransaction()){
  52. this.transactions.remove();
  53. connectionManager.setTransactionActive(false);
  54. connectionManager.releaseConnection(transaction.getConnection());
  55. }else{
  56. transaction.completeService();
  57. }
  58. }catch(Exceptione){
  59. thrownewTransactionException();
  60. }
  61. }
  62. /**
  63. *@return
  64. *@throwsClassNotFoundException
  65. *@throwsSQLException
  66. */
  67. /**
  68. *@returntheconnectionManager
  69. */
  70. publicConnectionManagergetConnectionManager(){
  71. returnconnectionManager;
  72. }
  73. /**
  74. *@paramconnectionManagertheconnectionManagertoset
  75. */
  76. publicvoidsetConnectionManager(ConnectionManagerconnectionManager){
  77. this.connectionManager=connectionManager;
  78. }
  79. publicvoidaddSavePoint(StringsavePointName,ExceptionrollbackException){
  80. Transactiontr=this.transactions.get();
  81. if(tr==null){
  82. tr=this.beginTransaction();
  83. }
  84. try{
  85. if(!tr.isSupportSavepoint()){
  86. thrownewSavePointNotSupportException();
  87. }
  88. tr.addSavepointAndRollbackException(savePointName,rollbackException);
  89. }catch(Exceptione){
  90. thrownewTransactionException();
  91. }
  92. }
  93. }


5. ConnectionManager对象的实现
Java代码 收藏代码
  1. publicclassConnectionManager{
  2. privatestaticConnectionManagerconnectionManager=newConnectionManager();
  3. ThreadLocal<Connection>threadConnection=newThreadLocal<Connection>();
  4. privateConnectionManager(){}
  5. publicstaticConnectionManagergetConnectionManager(){
  6. returnconnectionManager;
  7. }
  8. privateBooleanisTransactionActive=Boolean.FALSE;
  9. publicConnectiongetConnection()throwsClassNotFoundException,SQLException{
  10. Connectionconnection=this.threadConnection.get();
  11. if(connection==null){
  12. connection=(Connection)DriverManager.getConnection(
  13. "jdbc:sqlserver://10.171.30.11:1433;instanceName=nasa;databaseName=nasa2_SMS_PT;SelectMethod=cursor;characterEncoding=utf-8;autoReconnectForPools=true;autoReconnect=true",
  14. "sms","sms");
  15. this.threadConnection.set(connection);
  16. }
  17. returnconnection;
  18. }
  19. publicvoidreleaseConnection(Connectionconnection)throwsSQLException{
  20. if(!isTransactionActive){
  21. threadConnection.remove();
  22. connection.close();
  23. }
  24. }
  25. publicvoidcommit(Connectionconnection)throwsSQLException{
  26. if(!isTransactionActive){
  27. connection.commit();
  28. }
  29. }
  30. publicvoidrollback(Connectionconnection)throwsSQLException{
  31. if(!isTransactionActive){
  32. connection.rollback();
  33. }
  34. }
  35. publicvoidrollback(Connectionconnection,Savepointsavepoint)throwsSQLException{
  36. if(!isTransactionActive){
  37. connection.rollback(savepoint);
  38. }
  39. }
  40. /**
  41. *@paramisTransactionFinishedtheisTransactionFinishedtoset
  42. */
  43. publicvoidsetTransactionActive(BooleanisTransactionActive){
  44. this.isTransactionActive=isTransactionActive;
  45. }
  46. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值